| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: gencat.c,v 1.34 2011/12/29 22:58:27 wiz Exp $ */ | | 1 | /* $NetBSD: gencat.c,v 1.35 2012/03/09 18:54:28 ginsbach Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1996 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by J.T. Conklin. | | 8 | * by J.T. Conklin. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | #if defined(__RCSID) && !defined(lint) | | 33 | #if defined(__RCSID) && !defined(lint) |
34 | __RCSID("$NetBSD: gencat.c,v 1.34 2011/12/29 22:58:27 wiz Exp $"); | | 34 | __RCSID("$NetBSD: gencat.c,v 1.35 2012/03/09 18:54:28 ginsbach Exp $"); |
35 | #endif | | 35 | #endif |
36 | | | 36 | |
37 | /*********************************************************** | | 37 | /*********************************************************** |
38 | Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts. | | 38 | Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts. |
39 | | | 39 | |
40 | All Rights Reserved | | 40 | All Rights Reserved |
41 | | | 41 | |
42 | Permission to use, copy, modify, and distribute this software and its | | 42 | Permission to use, copy, modify, and distribute this software and its |
43 | documentation for any purpose and without fee is hereby granted, | | 43 | documentation for any purpose and without fee is hereby granted, |
44 | provided that the above copyright notice appear in all copies and that | | 44 | provided that the above copyright notice appear in all copies and that |
45 | both that copyright notice and this permission notice appear in | | 45 | both that copyright notice and this permission notice appear in |
46 | supporting documentation, and that Alfalfa's name not be used in | | 46 | supporting documentation, and that Alfalfa's name not be used in |
47 | advertising or publicity pertaining to distribution of the software | | 47 | advertising or publicity pertaining to distribution of the software |
| @@ -335,52 +335,69 @@ cskip(char *cptr) | | | @@ -335,52 +335,69 @@ cskip(char *cptr) |
335 | warning(cptr, "wasn't expecting a space"); | | 335 | warning(cptr, "wasn't expecting a space"); |
336 | return (cptr); | | 336 | return (cptr); |
337 | } | | 337 | } |
338 | while (*cptr && !isspace((unsigned char) *cptr)) | | 338 | while (*cptr && !isspace((unsigned char) *cptr)) |
339 | ++cptr; | | 339 | ++cptr; |
340 | return (cptr); | | 340 | return (cptr); |
341 | } | | 341 | } |
342 | | | 342 | |
343 | static char * | | 343 | static char * |
344 | getmsg(int fd, char *cptr, char quote) | | 344 | getmsg(int fd, char *cptr, char quote) |
345 | { | | 345 | { |
346 | static char *msg = NULL; | | 346 | static char *msg = NULL; |
347 | static size_t msglen = 0; | | 347 | static size_t msglen = 0; |
348 | size_t clen, i; | | 348 | size_t clen, i; |
| | | 349 | int in_quote = 0; |
349 | char *tptr; | | 350 | char *tptr; |
350 | | | 351 | |
351 | if (quote && *cptr == quote) { | | 352 | if (quote && *cptr == quote) { |
352 | ++cptr; | | 353 | ++cptr; |
| | | 354 | in_quote = 1; |
353 | } | | 355 | } |
354 | | | 356 | |
355 | clen = strlen(cptr) + 1; | | 357 | clen = strlen(cptr) + 1; |
356 | if (clen > msglen) { | | 358 | if (clen > msglen) { |
357 | if (msglen) | | 359 | if (msglen) |
358 | msg = xrealloc(msg, clen); | | 360 | msg = xrealloc(msg, clen); |
359 | else | | 361 | else |
360 | msg = xmalloc(clen); | | 362 | msg = xmalloc(clen); |
361 | msglen = clen; | | 363 | msglen = clen; |
362 | } | | 364 | } |
363 | tptr = msg; | | 365 | tptr = msg; |
364 | | | 366 | |
365 | while (*cptr) { | | 367 | while (*cptr) { |
366 | if (quote && *cptr == quote) { | | 368 | if (quote && *cptr == quote) { |
367 | char *tmp; | | 369 | char *tmp; |
368 | tmp = cptr + 1; | | 370 | tmp = cptr + 1; |
369 | if (*tmp && (!isspace((unsigned char) *tmp) || *wskip(tmp))) { | | 371 | if (!in_quote) { |
| | | 372 | /* XXX hard error? */ |
370 | warning(cptr, "unexpected quote character, ignoring"); | | 373 | warning(cptr, "unexpected quote character, ignoring"); |
371 | *tptr++ = *cptr++; | | 374 | *tptr++ = *cptr++; |
372 | } else { | | 375 | } else { |
373 | *cptr = '\0'; | | 376 | cptr++; |
| | | 377 | /* don't use wskip() */ |
| | | 378 | while (*cptr && isspace((unsigned char) *cptr)) |
| | | 379 | #ifndef _BACKWARDS_COMPAT |
| | | 380 | cptr++; |
| | | 381 | #else |
| | | 382 | *tptr++ = *cptr++; |
| | | 383 | #endif |
| | | 384 | /* XXX hard error? */ |
| | | 385 | if (*cptr) |
| | | 386 | warning(tmp, "unexpected extra characters, ignoring"); |
| | | 387 | in_quote = 0; |
| | | 388 | #ifndef _BACKWARDS_COMPAT |
| | | 389 | break; |
| | | 390 | #endif |
374 | } | | 391 | } |
375 | } else { | | 392 | } else { |
376 | if (*cptr == '\\') { | | 393 | if (*cptr == '\\') { |
377 | ++cptr; | | 394 | ++cptr; |
378 | switch (*cptr) { | | 395 | switch (*cptr) { |
379 | case '\0': | | 396 | case '\0': |
380 | cptr = get_line(fd); | | 397 | cptr = get_line(fd); |
381 | if (!cptr) | | 398 | if (!cptr) |
382 | error("premature end of file"); | | 399 | error("premature end of file"); |
383 | msglen += strlen(cptr); | | 400 | msglen += strlen(cptr); |
384 | i = tptr - msg; | | 401 | i = tptr - msg; |
385 | msg = xrealloc(msg, msglen); | | 402 | msg = xrealloc(msg, msglen); |
386 | tptr = msg + i; | | 403 | tptr = msg + i; |
| @@ -427,26 +444,30 @@ getmsg(int fd, char *cptr, char quote) | | | @@ -427,26 +444,30 @@ getmsg(int fd, char *cptr, char quote) |
427 | *tptr += (*cptr - '0'); | | 444 | *tptr += (*cptr - '0'); |
428 | ++cptr; | | 445 | ++cptr; |
429 | } | | 446 | } |
430 | } else { | | 447 | } else { |
431 | warning(cptr, "unrecognized escape sequence"); | | 448 | warning(cptr, "unrecognized escape sequence"); |
432 | } | | 449 | } |
433 | break; | | 450 | break; |
434 | } | | 451 | } |
435 | } else { | | 452 | } else { |
436 | *tptr++ = *cptr++; | | 453 | *tptr++ = *cptr++; |
437 | } | | 454 | } |
438 | } | | 455 | } |
439 | } | | 456 | } |
| | | 457 | |
| | | 458 | if (in_quote) |
| | | 459 | warning(cptr, "unterminated quoted message, ignoring"); |
| | | 460 | |
440 | *tptr = '\0'; | | 461 | *tptr = '\0'; |
441 | return (msg); | | 462 | return (msg); |
442 | } | | 463 | } |
443 | | | 464 | |
444 | static void | | 465 | static void |
445 | MCParse(int fd) | | 466 | MCParse(int fd) |
446 | { | | 467 | { |
447 | char *cptr, *str; | | 468 | char *cptr, *str; |
448 | int msgid = 0; | | 469 | int msgid = 0; |
449 | int setid = 0; | | 470 | int setid = 0; |
450 | char quote = 0; | | 471 | char quote = 0; |
451 | | | 472 | |
452 | /* XXX: init sethead? */ | | 473 | /* XXX: init sethead? */ |