File: | src/usr.bin/gencat/gencat.c |
Warning: | line 269, column 6 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: gencat.c,v 1.20 2019/07/25 13:53:57 schwarze Exp $ */ | ||||
2 | /* $NetBSD: gencat.c,v 1.9 1998/10/09 17:00:56 itohy Exp $ */ | ||||
3 | |||||
4 | /*- | ||||
5 | * Copyright (c) 1996 The NetBSD Foundation, Inc. | ||||
6 | * All rights reserved. | ||||
7 | * | ||||
8 | * This code is derived from software contributed to The NetBSD Foundation | ||||
9 | * by J.T. Conklin. | ||||
10 | * | ||||
11 | * Redistribution and use in source and binary forms, with or without | ||||
12 | * modification, are permitted provided that the following conditions | ||||
13 | * are met: | ||||
14 | * 1. Redistributions of source code must retain the above copyright | ||||
15 | * notice, this list of conditions and the following disclaimer. | ||||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||||
17 | * notice, this list of conditions and the following disclaimer in the | ||||
18 | * documentation and/or other materials provided with the distribution. | ||||
19 | * | ||||
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||||
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||||
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | ||||
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
30 | * POSSIBILITY OF SUCH DAMAGE. | ||||
31 | */ | ||||
32 | |||||
33 | |||||
34 | /*********************************************************** | ||||
35 | Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts. | ||||
36 | |||||
37 | All Rights Reserved | ||||
38 | |||||
39 | Permission to use, copy, modify, and distribute this software and its | ||||
40 | documentation for any purpose and without fee is hereby granted, | ||||
41 | provided that the above copyright notice appear in all copies and that | ||||
42 | both that copyright notice and this permission notice appear in | ||||
43 | supporting documentation, and that Alfalfa's name not be used in | ||||
44 | advertising or publicity pertaining to distribution of the software | ||||
45 | without specific, written prior permission. | ||||
46 | |||||
47 | ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | ||||
48 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | ||||
49 | ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | ||||
50 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | ||||
51 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||||
52 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||||
53 | SOFTWARE. | ||||
54 | |||||
55 | If you make any modifications, bugfixes or other changes to this software | ||||
56 | we'd appreciate it if you could send a copy to us so we can keep things | ||||
57 | up-to-date. Many thanks. | ||||
58 | Kee Hinckley | ||||
59 | Alfalfa Software, Inc. | ||||
60 | 267 Allston St., #3 | ||||
61 | Cambridge, MA 02139 USA | ||||
62 | nazgul@alfalfa.com | ||||
63 | |||||
64 | ******************************************************************/ | ||||
65 | |||||
66 | #define _NLS_PRIVATE | ||||
67 | |||||
68 | /* ensure 8-bit cleanliness */ | ||||
69 | #define ISSPACE(c)(isascii((unsigned char)c) && isspace((unsigned char) c)) \ | ||||
70 | (isascii((unsigned char)c) && isspace((unsigned char)c)) | ||||
71 | |||||
72 | #include <sys/queue.h> | ||||
73 | #include <ctype.h> | ||||
74 | #include <err.h> | ||||
75 | #include <fcntl.h> | ||||
76 | #include <nl_types.h> | ||||
77 | #include <stdio.h> | ||||
78 | #include <stdlib.h> | ||||
79 | #include <string.h> | ||||
80 | #include <unistd.h> | ||||
81 | |||||
82 | struct _msgT { | ||||
83 | long msgId; | ||||
84 | char *str; | ||||
85 | LIST_ENTRY(_msgT)struct { struct _msgT *le_next; struct _msgT **le_prev; } entries; | ||||
86 | }; | ||||
87 | |||||
88 | struct _setT { | ||||
89 | long setId; | ||||
90 | LIST_HEAD(msghead, _msgT)struct msghead { struct _msgT *lh_first; } msghead; | ||||
91 | LIST_ENTRY(_setT)struct { struct _setT *le_next; struct _setT **le_prev; } entries; | ||||
92 | }; | ||||
93 | |||||
94 | LIST_HEAD(sethead, _setT)struct sethead { struct _setT *lh_first; } sethead; | ||||
95 | static struct _setT *curSet; | ||||
96 | |||||
97 | static char *curline = NULL((void *)0); | ||||
98 | static long lineno = 0; | ||||
99 | |||||
100 | extern char *__progname; /* from crt0.o */ | ||||
101 | |||||
102 | static char *cskip(char *); | ||||
103 | static void error(char *, char *); | ||||
104 | static void nomem(void); | ||||
105 | static char *get_line(int); | ||||
106 | static char *getmsg(int, char *, char); | ||||
107 | static void warning(char *, char *); | ||||
108 | static char *wskip(char *); | ||||
109 | static char *xstrdup(const char *); | ||||
110 | static void *xmalloc(size_t); | ||||
111 | static void *xrealloc(void *, size_t); | ||||
112 | |||||
113 | void MCParse(int fd); | ||||
114 | void MCWriteCat(int fd); | ||||
115 | void MCDelMsg(int msgId); | ||||
116 | void MCAddMsg(int msgId, const char *msg); | ||||
117 | void MCAddSet(int setId); | ||||
118 | void MCDelSet(int setId); | ||||
119 | int main(int, char **); | ||||
120 | void usage(void); | ||||
121 | |||||
122 | |||||
123 | void | ||||
124 | usage(void) | ||||
125 | { | ||||
126 | fprintf(stderr(&__sF[2]), "usage: %s catfile msgfile ...\n", __progname); | ||||
127 | exit(1); | ||||
128 | } | ||||
129 | |||||
130 | int | ||||
131 | main(int argc, char *argv[]) | ||||
132 | { | ||||
133 | int ofd, ifd; | ||||
134 | char *catfile = NULL((void *)0); | ||||
135 | int c; | ||||
136 | |||||
137 | if (pledge("stdio rpath wpath cpath", NULL((void *)0)) == -1) | ||||
| |||||
138 | err(1, "pledge"); | ||||
139 | |||||
140 | while ((c = getopt(argc, argv, "")) != -1) { | ||||
141 | switch (c) { | ||||
142 | case '?': | ||||
143 | default: | ||||
144 | usage(); | ||||
145 | /* NOTREACHED */ | ||||
146 | } | ||||
147 | } | ||||
148 | argc -= optind; | ||||
149 | argv += optind; | ||||
150 | |||||
151 | if (argc < 2) { | ||||
152 | usage(); | ||||
153 | /* NOTREACHED */ | ||||
154 | } | ||||
155 | catfile = *argv++; | ||||
156 | |||||
157 | for (; *argv; argv++) { | ||||
158 | if ((ifd = open(*argv, O_RDONLY0x0000)) == -1) | ||||
159 | err(1, "Unable to read %s", *argv); | ||||
160 | MCParse(ifd); | ||||
161 | close(ifd); | ||||
162 | } | ||||
163 | |||||
164 | if ((ofd = open(catfile, O_WRONLY0x0001 | O_TRUNC0x0400 | O_CREAT0x0200, 0666)) == -1) | ||||
165 | err(1, "Unable to create a new %s", catfile); | ||||
166 | MCWriteCat(ofd); | ||||
167 | exit(0); | ||||
168 | } | ||||
169 | |||||
170 | static void | ||||
171 | warning(char *cptr, char *msg) | ||||
172 | { | ||||
173 | warnx("%s on line %ld\n%s", msg, lineno, curline); | ||||
174 | if (cptr) { | ||||
175 | char *tptr; | ||||
176 | for (tptr = curline; tptr < cptr; ++tptr) | ||||
177 | putc(' ', stderr)(!__isthreaded ? __sputc(' ', (&__sF[2])) : (putc)(' ', ( &__sF[2]))); | ||||
178 | fprintf(stderr(&__sF[2]), "^\n"); | ||||
179 | } | ||||
180 | } | ||||
181 | |||||
182 | static void | ||||
183 | error(char *cptr, char *msg) | ||||
184 | { | ||||
185 | warning(cptr, msg); | ||||
186 | exit(1); | ||||
187 | } | ||||
188 | |||||
189 | static void | ||||
190 | nomem(void) | ||||
191 | { | ||||
192 | error(NULL((void *)0), "out of memory"); | ||||
193 | } | ||||
194 | |||||
195 | static void * | ||||
196 | xmalloc(size_t len) | ||||
197 | { | ||||
198 | void *p; | ||||
199 | |||||
200 | if ((p = malloc(len)) == NULL((void *)0)) | ||||
201 | nomem(); | ||||
202 | return (p); | ||||
203 | } | ||||
204 | |||||
205 | static void * | ||||
206 | xrealloc(void *ptr, size_t size) | ||||
207 | { | ||||
208 | if ((ptr = realloc(ptr, size)) == NULL((void *)0)) | ||||
209 | nomem(); | ||||
210 | return (ptr); | ||||
211 | } | ||||
212 | |||||
213 | static char * | ||||
214 | xstrdup(const char *str) | ||||
215 | { | ||||
216 | char *nstr; | ||||
217 | |||||
218 | if ((nstr = strdup(str)) == NULL((void *)0)) | ||||
219 | nomem(); | ||||
220 | return (nstr); | ||||
221 | } | ||||
222 | |||||
223 | static char * | ||||
224 | get_line(int fd) | ||||
225 | { | ||||
226 | static long curlen = BUFSIZ1024; | ||||
227 | static char buf[BUFSIZ1024], *bptr = buf, *bend = buf; | ||||
228 | char *cptr, *cend; | ||||
229 | long buflen; | ||||
230 | |||||
231 | if (!curline
| ||||
232 | curline = xmalloc(curlen); | ||||
233 | } | ||||
234 | ++lineno; | ||||
235 | |||||
236 | cptr = curline; | ||||
237 | cend = curline + curlen; | ||||
238 | for (;;) { | ||||
239 | for (; bptr
| ||||
240 | if (*bptr == '\n') { | ||||
241 | *cptr = '\0'; | ||||
242 | ++bptr; | ||||
243 | return (curline); | ||||
244 | } else | ||||
245 | *cptr = *bptr; | ||||
246 | } | ||||
247 | if (bptr
| ||||
248 | buflen = read(fd, buf, BUFSIZ1024); | ||||
249 | if (buflen <= 0) { | ||||
250 | if (cptr > curline) { | ||||
251 | *cptr = '\0'; | ||||
252 | return (curline); | ||||
253 | } | ||||
254 | return (NULL((void *)0)); | ||||
255 | } | ||||
256 | bend = buf + buflen; | ||||
257 | bptr = buf; | ||||
258 | } | ||||
259 | if (cptr
| ||||
260 | cptr = curline = xrealloc(curline, curlen *= 2); | ||||
261 | cend = curline + curlen; | ||||
262 | } | ||||
263 | } | ||||
264 | } | ||||
265 | |||||
266 | static char * | ||||
267 | wskip(char *cptr) | ||||
268 | { | ||||
269 | if (!*cptr || !ISSPACE(*cptr)(isascii((unsigned char)*cptr) && isspace((unsigned char )*cptr))) { | ||||
| |||||
270 | warning(cptr, "expected a space"); | ||||
271 | return (cptr); | ||||
272 | } | ||||
273 | while (*cptr && ISSPACE(*cptr)(isascii((unsigned char)*cptr) && isspace((unsigned char )*cptr))) | ||||
274 | ++cptr; | ||||
275 | return (cptr); | ||||
276 | } | ||||
277 | |||||
278 | static char * | ||||
279 | cskip(char *cptr) | ||||
280 | { | ||||
281 | if (!*cptr || ISSPACE(*cptr)(isascii((unsigned char)*cptr) && isspace((unsigned char )*cptr))) { | ||||
282 | warning(cptr, "wasn't expecting a space"); | ||||
283 | return (cptr); | ||||
284 | } | ||||
285 | while (*cptr && !ISSPACE(*cptr)(isascii((unsigned char)*cptr) && isspace((unsigned char )*cptr))) | ||||
286 | ++cptr; | ||||
287 | return (cptr); | ||||
288 | } | ||||
289 | |||||
290 | static char * | ||||
291 | getmsg(int fd, char *cptr, char quote) | ||||
292 | { | ||||
293 | static char *msg = NULL((void *)0); | ||||
294 | static long msglen = 0; | ||||
295 | long clen, i; | ||||
296 | char *tptr; | ||||
297 | |||||
298 | if (quote && *cptr == quote) { | ||||
299 | ++cptr; | ||||
300 | } | ||||
301 | |||||
302 | clen = strlen(cptr) + 1; | ||||
303 | if (clen > msglen) { | ||||
304 | if (msglen) | ||||
305 | msg = xrealloc(msg, clen); | ||||
306 | else | ||||
307 | msg = xmalloc(clen); | ||||
308 | msglen = clen; | ||||
309 | } | ||||
310 | tptr = msg; | ||||
311 | |||||
312 | while (*cptr) { | ||||
313 | if (quote && *cptr == quote) { | ||||
314 | char *tmp; | ||||
315 | tmp = cptr + 1; | ||||
316 | |||||
317 | if (*tmp && (!ISSPACE(*tmp)(isascii((unsigned char)*tmp) && isspace((unsigned char )*tmp)) || *wskip(tmp))) { | ||||
318 | warning(cptr, "unexpected quote character, ignoring"); | ||||
319 | *tptr++ = *cptr++; | ||||
320 | } else { | ||||
321 | *cptr = '\0'; | ||||
322 | } | ||||
323 | } else if (*cptr == '\\') { | ||||
324 | ++cptr; | ||||
325 | switch (*cptr) { | ||||
326 | case '\0': | ||||
327 | cptr = get_line(fd); | ||||
328 | if (!cptr) | ||||
329 | error(NULL((void *)0), "premature end of file"); | ||||
330 | msglen += strlen(cptr); | ||||
331 | i = tptr - msg; | ||||
332 | msg = xrealloc(msg, msglen); | ||||
333 | tptr = msg + i; | ||||
334 | break; | ||||
335 | case 'n': | ||||
336 | *tptr++ = '\n'; | ||||
337 | ++cptr; | ||||
338 | break; | ||||
339 | case 't': | ||||
340 | *tptr++ = '\t'; | ||||
341 | ++cptr; | ||||
342 | break; | ||||
343 | case 'v': | ||||
344 | *tptr++ = '\v'; | ||||
345 | ++cptr; | ||||
346 | break; | ||||
347 | case 'b': | ||||
348 | *tptr++ = '\b'; | ||||
349 | ++cptr; | ||||
350 | break; | ||||
351 | case 'r': | ||||
352 | *tptr++ = '\r'; | ||||
353 | ++cptr; | ||||
354 | break; | ||||
355 | case 'f': | ||||
356 | *tptr++ = '\f'; | ||||
357 | ++cptr; | ||||
358 | break; | ||||
359 | case '\\': | ||||
360 | *tptr++ = '\\'; | ||||
361 | ++cptr; | ||||
362 | break; | ||||
363 | case '"': | ||||
364 | /* FALLTHROUGH */ | ||||
365 | case '\'': | ||||
366 | /* | ||||
367 | * While it isn't necessary to | ||||
368 | * escape ' and ", let's accept | ||||
369 | * them escaped and not complain. | ||||
370 | * (XPG4 states that '\' should be | ||||
371 | * ignored when not used in a | ||||
372 | * valid escape sequence) | ||||
373 | */ | ||||
374 | *tptr++ = '"'; | ||||
375 | ++cptr; | ||||
376 | break; | ||||
377 | default: | ||||
378 | if (quote && *cptr == quote) { | ||||
379 | *tptr++ = *cptr++; | ||||
380 | } else if (isdigit((unsigned char) *cptr)) { | ||||
381 | *tptr = 0; | ||||
382 | for (i = 0; i < 3; ++i) { | ||||
383 | if (!isdigit((unsigned char) *cptr)) | ||||
384 | break; | ||||
385 | if (*cptr > '7') | ||||
386 | warning(cptr, "octal number greater than 7?!"); | ||||
387 | *tptr *= 8; | ||||
388 | *tptr += (*cptr - '0'); | ||||
389 | ++cptr; | ||||
390 | } | ||||
391 | } else { | ||||
392 | warning(cptr, "unrecognized escape sequence; ignoring esacpe character"); | ||||
393 | } | ||||
394 | break; | ||||
395 | } | ||||
396 | } else { | ||||
397 | *tptr++ = *cptr++; | ||||
398 | } | ||||
399 | } | ||||
400 | *tptr = '\0'; | ||||
401 | return (msg); | ||||
402 | } | ||||
403 | |||||
404 | void | ||||
405 | MCParse(int fd) | ||||
406 | { | ||||
407 | char *cptr, *str; | ||||
408 | int setid, msgid; | ||||
409 | char quote = 0; | ||||
410 | |||||
411 | /* XXX: init sethead? */ | ||||
412 | |||||
413 | setid = 0; | ||||
414 | while ((cptr = get_line(fd))) { | ||||
415 | if (*cptr == '$') { | ||||
416 | ++cptr; | ||||
417 | if (strncmp(cptr, "set", 3) == 0) { | ||||
418 | cptr += 3; | ||||
419 | cptr = wskip(cptr); | ||||
420 | setid = atoi(cptr); | ||||
421 | MCAddSet(setid); | ||||
422 | } else if (strncmp(cptr, "delset", 6) == 0) { | ||||
423 | cptr += 6; | ||||
424 | cptr = wskip(cptr); | ||||
425 | setid = atoi(cptr); | ||||
426 | MCDelSet(setid); | ||||
427 | } else if (strncmp(cptr, "quote", 5) == 0) { | ||||
428 | cptr += 5; | ||||
429 | if (!*cptr) | ||||
430 | quote = 0; | ||||
431 | else { | ||||
432 | cptr = wskip(cptr); | ||||
433 | if (!*cptr) | ||||
434 | quote = 0; | ||||
435 | else | ||||
436 | quote = *cptr; | ||||
437 | } | ||||
438 | } else if (ISSPACE(*cptr)(isascii((unsigned char)*cptr) && isspace((unsigned char )*cptr))) { | ||||
439 | ; | ||||
440 | } else { | ||||
441 | if (*cptr) { | ||||
442 | cptr = wskip(cptr); | ||||
443 | if (*cptr) | ||||
444 | warning(cptr, "unrecognized line"); | ||||
445 | } | ||||
446 | } | ||||
447 | } else { | ||||
448 | /* | ||||
449 | * First check for (and eat) empty lines.... | ||||
450 | */ | ||||
451 | if (!*cptr) | ||||
452 | continue; | ||||
453 | /* | ||||
454 | * We have a digit? Start of a message. Else, | ||||
455 | * syntax error. | ||||
456 | */ | ||||
457 | if (isdigit((unsigned char) *cptr)) { | ||||
458 | msgid = atoi(cptr); | ||||
459 | cptr = cskip(cptr); | ||||
460 | cptr = wskip(cptr); | ||||
461 | /* if (*cptr) ++cptr; */ | ||||
462 | } else { | ||||
463 | warning(cptr, "neither blank line nor start of a message id"); | ||||
464 | continue; | ||||
465 | } | ||||
466 | if (setid == 0) { | ||||
467 | setid = NL_SETD1; | ||||
468 | MCAddSet(setid); | ||||
469 | } | ||||
470 | /* | ||||
471 | * If we have a message ID, but no message, | ||||
472 | * then this means "delete this message id | ||||
473 | * from the catalog". | ||||
474 | */ | ||||
475 | if (!*cptr) { | ||||
476 | MCDelMsg(msgid); | ||||
477 | } else { | ||||
478 | str = getmsg(fd, cptr, quote); | ||||
479 | MCAddMsg(msgid, str); | ||||
480 | } | ||||
481 | } | ||||
482 | } | ||||
483 | } | ||||
484 | |||||
485 | /* | ||||
486 | * Write message catalog. | ||||
487 | * | ||||
488 | * The message catalog is first converted from its internal to its | ||||
489 | * external representation in a chunk of memory allocated for this | ||||
490 | * purpose. Then the completed catalog is written. This approach | ||||
491 | * avoids additional housekeeping variables and/or a lot of seeks | ||||
492 | * that would otherwise be required. | ||||
493 | */ | ||||
494 | void | ||||
495 | MCWriteCat(int fd) | ||||
496 | { | ||||
497 | int nsets; /* number of sets */ | ||||
498 | int nmsgs; /* number of msgs */ | ||||
499 | int string_size; /* total size of string pool */ | ||||
500 | int msgcat_size; /* total size of message catalog */ | ||||
501 | void *msgcat; /* message catalog data */ | ||||
502 | struct _nls_cat_hdr *cat_hdr; | ||||
503 | struct _nls_set_hdr *set_hdr; | ||||
504 | struct _nls_msg_hdr *msg_hdr; | ||||
505 | char *strings; | ||||
506 | struct _setT *set; | ||||
507 | struct _msgT *msg; | ||||
508 | int msg_index; | ||||
509 | int msg_offset; | ||||
510 | |||||
511 | /* determine number of sets, number of messages, and size of the | ||||
512 | * string pool */ | ||||
513 | nsets = 0; | ||||
514 | nmsgs = 0; | ||||
515 | string_size = 0; | ||||
516 | |||||
517 | LIST_FOREACH(set, &sethead, entries)for((set) = ((&sethead)->lh_first); (set)!= ((void *)0 ); (set) = ((set)->entries.le_next)) { | ||||
518 | nsets++; | ||||
519 | |||||
520 | LIST_FOREACH(msg, &set->msghead, entries)for((msg) = ((&set->msghead)->lh_first); (msg)!= (( void *)0); (msg) = ((msg)->entries.le_next)) { | ||||
521 | nmsgs++; | ||||
522 | string_size += strlen(msg->str) + 1; | ||||
523 | } | ||||
524 | } | ||||
525 | |||||
526 | #ifdef DEBUG | ||||
527 | printf("number of sets: %d\n", nsets); | ||||
528 | printf("number of msgs: %d\n", nmsgs); | ||||
529 | printf("string pool size: %d\n", string_size); | ||||
530 | #endif | ||||
531 | |||||
532 | /* determine size and then allocate buffer for constructing external | ||||
533 | * message catalog representation */ | ||||
534 | msgcat_size = sizeof(struct _nls_cat_hdr) | ||||
535 | + (nsets * sizeof(struct _nls_set_hdr)) | ||||
536 | + (nmsgs * sizeof(struct _nls_msg_hdr)) | ||||
537 | + string_size; | ||||
538 | |||||
539 | msgcat = xmalloc(msgcat_size); | ||||
540 | memset(msgcat, '\0', msgcat_size); | ||||
541 | |||||
542 | /* fill in msg catalog header */ | ||||
543 | cat_hdr = (struct _nls_cat_hdr *) msgcat; | ||||
544 | cat_hdr->__magic = htonl(_NLS_MAGIC)(__uint32_t)(__builtin_constant_p(0xff88ff89) ? (__uint32_t)( ((__uint32_t)(0xff88ff89) & 0xff) << 24 | ((__uint32_t )(0xff88ff89) & 0xff00) << 8 | ((__uint32_t)(0xff88ff89 ) & 0xff0000) >> 8 | ((__uint32_t)(0xff88ff89) & 0xff000000) >> 24) : __swap32md(0xff88ff89)); | ||||
545 | cat_hdr->__nsets = htonl(nsets)(__uint32_t)(__builtin_constant_p(nsets) ? (__uint32_t)(((__uint32_t )(nsets) & 0xff) << 24 | ((__uint32_t)(nsets) & 0xff00) << 8 | ((__uint32_t)(nsets) & 0xff0000) >> 8 | ((__uint32_t)(nsets) & 0xff000000) >> 24) : __swap32md (nsets)); | ||||
546 | cat_hdr->__mem = htonl(msgcat_size - sizeof(struct _nls_cat_hdr))(__uint32_t)(__builtin_constant_p(msgcat_size - sizeof(struct _nls_cat_hdr)) ? (__uint32_t)(((__uint32_t)(msgcat_size - sizeof (struct _nls_cat_hdr)) & 0xff) << 24 | ((__uint32_t )(msgcat_size - sizeof(struct _nls_cat_hdr)) & 0xff00) << 8 | ((__uint32_t)(msgcat_size - sizeof(struct _nls_cat_hdr)) & 0xff0000) >> 8 | ((__uint32_t)(msgcat_size - sizeof (struct _nls_cat_hdr)) & 0xff000000) >> 24) : __swap32md (msgcat_size - sizeof(struct _nls_cat_hdr))); | ||||
547 | cat_hdr->__msg_hdr_offset = | ||||
548 | htonl(nsets * sizeof(struct _nls_set_hdr))(__uint32_t)(__builtin_constant_p(nsets * sizeof(struct _nls_set_hdr )) ? (__uint32_t)(((__uint32_t)(nsets * sizeof(struct _nls_set_hdr )) & 0xff) << 24 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr)) & 0xff00) << 8 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr)) & 0xff0000) >> 8 | ( (__uint32_t)(nsets * sizeof(struct _nls_set_hdr)) & 0xff000000 ) >> 24) : __swap32md(nsets * sizeof(struct _nls_set_hdr ))); | ||||
549 | cat_hdr->__msg_txt_offset = | ||||
550 | htonl(nsets * sizeof(struct _nls_set_hdr) +(__uint32_t)(__builtin_constant_p(nsets * sizeof(struct _nls_set_hdr ) + nmsgs * sizeof(struct _nls_msg_hdr)) ? (__uint32_t)(((__uint32_t )(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr)) & 0xff) << 24 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr )) & 0xff00) << 8 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr)) & 0xff0000 ) >> 8 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr ) + nmsgs * sizeof(struct _nls_msg_hdr)) & 0xff000000) >> 24) : __swap32md(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr))) | ||||
551 | nmsgs * sizeof(struct _nls_msg_hdr))(__uint32_t)(__builtin_constant_p(nsets * sizeof(struct _nls_set_hdr ) + nmsgs * sizeof(struct _nls_msg_hdr)) ? (__uint32_t)(((__uint32_t )(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr)) & 0xff) << 24 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr )) & 0xff00) << 8 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr)) & 0xff0000 ) >> 8 | ((__uint32_t)(nsets * sizeof(struct _nls_set_hdr ) + nmsgs * sizeof(struct _nls_msg_hdr)) & 0xff000000) >> 24) : __swap32md(nsets * sizeof(struct _nls_set_hdr) + nmsgs * sizeof(struct _nls_msg_hdr))); | ||||
552 | |||||
553 | /* compute offsets for set & msg header tables and string pool */ | ||||
554 | set_hdr = (struct _nls_set_hdr *) ((char *) msgcat + | ||||
555 | sizeof(struct _nls_cat_hdr)); | ||||
556 | msg_hdr = (struct _nls_msg_hdr *) ((char *) msgcat + | ||||
557 | sizeof(struct _nls_cat_hdr) + | ||||
558 | nsets * sizeof(struct _nls_set_hdr)); | ||||
559 | strings = (char *) msgcat + | ||||
560 | sizeof(struct _nls_cat_hdr) + | ||||
561 | nsets * sizeof(struct _nls_set_hdr) + | ||||
562 | nmsgs * sizeof(struct _nls_msg_hdr); | ||||
563 | |||||
564 | msg_index = 0; | ||||
565 | msg_offset = 0; | ||||
566 | LIST_FOREACH(set, &sethead, entries)for((set) = ((&sethead)->lh_first); (set)!= ((void *)0 ); (set) = ((set)->entries.le_next)) { | ||||
567 | |||||
568 | nmsgs = 0; | ||||
569 | LIST_FOREACH(msg, &set->msghead, entries)for((msg) = ((&set->msghead)->lh_first); (msg)!= (( void *)0); (msg) = ((msg)->entries.le_next)) { | ||||
570 | int msg_len = strlen(msg->str) + 1; | ||||
571 | |||||
572 | msg_hdr->__msgno = htonl(msg->msgId)(__uint32_t)(__builtin_constant_p(msg->msgId) ? (__uint32_t )(((__uint32_t)(msg->msgId) & 0xff) << 24 | ((__uint32_t )(msg->msgId) & 0xff00) << 8 | ((__uint32_t)(msg ->msgId) & 0xff0000) >> 8 | ((__uint32_t)(msg-> msgId) & 0xff000000) >> 24) : __swap32md(msg->msgId )); | ||||
573 | msg_hdr->__msglen = htonl(msg_len)(__uint32_t)(__builtin_constant_p(msg_len) ? (__uint32_t)(((__uint32_t )(msg_len) & 0xff) << 24 | ((__uint32_t)(msg_len) & 0xff00) << 8 | ((__uint32_t)(msg_len) & 0xff0000) >> 8 | ((__uint32_t)(msg_len) & 0xff000000) >> 24) : __swap32md (msg_len)); | ||||
574 | msg_hdr->__offset = htonl(msg_offset)(__uint32_t)(__builtin_constant_p(msg_offset) ? (__uint32_t)( ((__uint32_t)(msg_offset) & 0xff) << 24 | ((__uint32_t )(msg_offset) & 0xff00) << 8 | ((__uint32_t)(msg_offset ) & 0xff0000) >> 8 | ((__uint32_t)(msg_offset) & 0xff000000) >> 24) : __swap32md(msg_offset)); | ||||
575 | |||||
576 | memcpy(strings, msg->str, msg_len); | ||||
577 | strings += msg_len; | ||||
578 | msg_offset += msg_len; | ||||
579 | |||||
580 | nmsgs++; | ||||
581 | msg_hdr++; | ||||
582 | } | ||||
583 | |||||
584 | set_hdr->__setno = htonl(set->setId)(__uint32_t)(__builtin_constant_p(set->setId) ? (__uint32_t )(((__uint32_t)(set->setId) & 0xff) << 24 | ((__uint32_t )(set->setId) & 0xff00) << 8 | ((__uint32_t)(set ->setId) & 0xff0000) >> 8 | ((__uint32_t)(set-> setId) & 0xff000000) >> 24) : __swap32md(set->setId )); | ||||
585 | set_hdr->__nmsgs = htonl(nmsgs)(__uint32_t)(__builtin_constant_p(nmsgs) ? (__uint32_t)(((__uint32_t )(nmsgs) & 0xff) << 24 | ((__uint32_t)(nmsgs) & 0xff00) << 8 | ((__uint32_t)(nmsgs) & 0xff0000) >> 8 | ((__uint32_t)(nmsgs) & 0xff000000) >> 24) : __swap32md (nmsgs)); | ||||
586 | set_hdr->__index = htonl(msg_index)(__uint32_t)(__builtin_constant_p(msg_index) ? (__uint32_t)(( (__uint32_t)(msg_index) & 0xff) << 24 | ((__uint32_t )(msg_index) & 0xff00) << 8 | ((__uint32_t)(msg_index ) & 0xff0000) >> 8 | ((__uint32_t)(msg_index) & 0xff000000) >> 24) : __swap32md(msg_index)); | ||||
587 | msg_index += nmsgs; | ||||
588 | set_hdr++; | ||||
589 | } | ||||
590 | |||||
591 | /* write out catalog. XXX: should this be done in small chunks? */ | ||||
592 | write(fd, msgcat, msgcat_size); | ||||
593 | } | ||||
594 | |||||
595 | void | ||||
596 | MCAddSet(int setId) | ||||
597 | { | ||||
598 | struct _setT *p, *q; | ||||
599 | |||||
600 | if (setId <= 0) { | ||||
601 | error(NULL((void *)0), "setId's must be greater than zero"); | ||||
602 | /* NOTREACHED */ | ||||
603 | } | ||||
604 | #if 0 | ||||
605 | /* XXX */ | ||||
606 | if (setId > NL_SETMAX) { | ||||
607 | error(NULL((void *)0), "setId %d exceeds limit (%d)"); | ||||
608 | /* NOTREACHED */ | ||||
609 | } | ||||
610 | #endif | ||||
611 | |||||
612 | p = LIST_FIRST(&sethead)((&sethead)->lh_first); | ||||
613 | q = NULL((void *)0); | ||||
614 | for (; p != NULL((void *)0) && p->setId < setId; q = p, p = LIST_NEXT(p, entries)((p)->entries.le_next)); | ||||
615 | |||||
616 | if (p && p->setId == setId) { | ||||
617 | ; | ||||
618 | } else { | ||||
619 | p = xmalloc(sizeof(struct _setT)); | ||||
620 | memset(p, '\0', sizeof(struct _setT)); | ||||
621 | LIST_INIT(&p->msghead)do { ((&p->msghead)->lh_first) = ((void *)0); } while (0); | ||||
622 | |||||
623 | p->setId = setId; | ||||
624 | |||||
625 | if (q == NULL((void *)0)) { | ||||
626 | LIST_INSERT_HEAD(&sethead, p, entries)do { if (((p)->entries.le_next = (&sethead)->lh_first ) != ((void *)0)) (&sethead)->lh_first->entries.le_prev = &(p)->entries.le_next; (&sethead)->lh_first = (p); (p)->entries.le_prev = &(&sethead)->lh_first ; } while (0); | ||||
627 | } else { | ||||
628 | LIST_INSERT_AFTER(q, p, entries)do { if (((p)->entries.le_next = (q)->entries.le_next) != ((void *)0)) (q)->entries.le_next->entries.le_prev = & (p)->entries.le_next; (q)->entries.le_next = (p); (p)-> entries.le_prev = &(q)->entries.le_next; } while (0); | ||||
629 | } | ||||
630 | } | ||||
631 | |||||
632 | curSet = p; | ||||
633 | } | ||||
634 | |||||
635 | void | ||||
636 | MCAddMsg(int msgId, const char *str) | ||||
637 | { | ||||
638 | struct _msgT *p, *q; | ||||
639 | |||||
640 | if (!curSet) | ||||
641 | error(NULL((void *)0), "can't specify a message when no set exists"); | ||||
642 | |||||
643 | if (msgId <= 0) { | ||||
644 | error(NULL((void *)0), "msgId's must be greater than zero"); | ||||
645 | /* NOTREACHED */ | ||||
646 | } | ||||
647 | #if 0 | ||||
648 | /* XXX */ | ||||
649 | if (msgId > NL_SETMAX) { | ||||
650 | error(NULL((void *)0), "msgId %d exceeds limit (%d)"); | ||||
651 | /* NOTREACHED */ | ||||
652 | } | ||||
653 | #endif | ||||
654 | |||||
655 | p = LIST_FIRST(&curSet->msghead)((&curSet->msghead)->lh_first); | ||||
656 | q = NULL((void *)0); | ||||
657 | for (; p != NULL((void *)0) && p->msgId < msgId; q = p, p = LIST_NEXT(p, entries)((p)->entries.le_next)); | ||||
658 | |||||
659 | if (p && p->msgId == msgId) { | ||||
660 | free(p->str); | ||||
661 | } else { | ||||
662 | p = xmalloc(sizeof(struct _msgT)); | ||||
663 | memset(p, '\0', sizeof(struct _msgT)); | ||||
664 | |||||
665 | if (q == NULL((void *)0)) { | ||||
666 | LIST_INSERT_HEAD(&curSet->msghead, p, entries)do { if (((p)->entries.le_next = (&curSet->msghead) ->lh_first) != ((void *)0)) (&curSet->msghead)-> lh_first->entries.le_prev = &(p)->entries.le_next; ( &curSet->msghead)->lh_first = (p); (p)->entries. le_prev = &(&curSet->msghead)->lh_first; } while (0); | ||||
667 | } else { | ||||
668 | LIST_INSERT_AFTER(q, p, entries)do { if (((p)->entries.le_next = (q)->entries.le_next) != ((void *)0)) (q)->entries.le_next->entries.le_prev = & (p)->entries.le_next; (q)->entries.le_next = (p); (p)-> entries.le_prev = &(q)->entries.le_next; } while (0); | ||||
669 | } | ||||
670 | } | ||||
671 | |||||
672 | p->msgId = msgId; | ||||
673 | p->str = xstrdup(str); | ||||
674 | } | ||||
675 | |||||
676 | void | ||||
677 | MCDelSet(int setId) | ||||
678 | { | ||||
679 | struct _setT *set; | ||||
680 | struct _msgT *msg; | ||||
681 | |||||
682 | set = LIST_FIRST(&sethead)((&sethead)->lh_first); | ||||
683 | for (; set != NULL((void *)0) && set->setId < setId; | ||||
684 | set = LIST_NEXT(set, entries)((set)->entries.le_next)); | ||||
685 | |||||
686 | if (set && set->setId == setId) { | ||||
687 | |||||
688 | msg = LIST_FIRST(&set->msghead)((&set->msghead)->lh_first); | ||||
689 | while (msg) { | ||||
690 | free(msg->str); | ||||
691 | LIST_REMOVE(msg, entries)do { if ((msg)->entries.le_next != ((void *)0)) (msg)-> entries.le_next->entries.le_prev = (msg)->entries.le_prev ; *(msg)->entries.le_prev = (msg)->entries.le_next; ; ; } while (0); | ||||
692 | } | ||||
693 | |||||
694 | LIST_REMOVE(set, entries)do { if ((set)->entries.le_next != ((void *)0)) (set)-> entries.le_next->entries.le_prev = (set)->entries.le_prev ; *(set)->entries.le_prev = (set)->entries.le_next; ; ; } while (0); | ||||
695 | return; | ||||
696 | } | ||||
697 | warning(NULL((void *)0), "specified set doesn't exist"); | ||||
698 | } | ||||
699 | |||||
700 | void | ||||
701 | MCDelMsg(int msgId) | ||||
702 | { | ||||
703 | struct _msgT *msg; | ||||
704 | |||||
705 | if (!curSet) | ||||
706 | error(NULL((void *)0), "you can't delete a message before defining the set"); | ||||
707 | |||||
708 | msg = LIST_FIRST(&curSet->msghead)((&curSet->msghead)->lh_first); | ||||
709 | for (; msg != NULL((void *)0) && msg->msgId < msgId; | ||||
710 | msg = LIST_NEXT(msg, entries)((msg)->entries.le_next)); | ||||
711 | |||||
712 | if (msg && msg->msgId == msgId) { | ||||
713 | free(msg->str); | ||||
714 | LIST_REMOVE(msg, entries)do { if ((msg)->entries.le_next != ((void *)0)) (msg)-> entries.le_next->entries.le_prev = (msg)->entries.le_prev ; *(msg)->entries.le_prev = (msg)->entries.le_next; ; ; } while (0); | ||||
715 | return; | ||||
716 | } | ||||
717 | warning(NULL((void *)0), "specified msg doesn't exist"); | ||||
718 | } |