[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Regression in gettext-0.13.1: produces corrupt pot-file
From: |
Bruno Haible |
Subject: |
Re: Regression in gettext-0.13.1: produces corrupt pot-file |
Date: |
Fri, 16 Jan 2004 13:13:10 +0100 |
User-agent: |
KMail/1.5 |
Erik Sigra wrote:
> I upgraded to gettext-0.13.1 but it failed. The reason is that it does not
> recognize the comment "/* xgettext:no-c-format */" in one place in the
> sourcecode. Therefore xgettext refuses to create the gmo-file, because it
> believes that there is something wrong with the format arguments. The
> sourcecode is:
>
> GEN_INT("diplchance", game.diplchance, SSET_RULES_FLEXIBLE,
> SSET_TO_CLIENT, N_("Chance in diplomat/spy contests"),
> /* xgettext:no-c-format */
> N_("A Diplomat or Spy acting against a city which has one or "
> "more defending Diplomats or Spies has a diplchance "
> "(percent) chance to defeat each such defender. Also, the "
> "chance of a Spy returning from a successful mission is "
> "diplchance percent. (Diplomats never return.) Also, a "
> "basic chance of success for Diplomats and Spies. "
> "Defending Spys are generally twice as capable as "
> "Diplomats, veteran units 50% more capable than "
> "non-veteran ones."), NULL,
> GAME_MIN_DIPLCHANCE, GAME_MAX_DIPLCHANCE, GAME_DEFAULT_DIPLCHANCE)
Thanks for reporting this. The appended patch should fix it,
Bruno
*** gettext-tools/src/x-c.c 30 Dec 2003 11:33:18 -0000 1.15
--- gettext-tools/src/x-c.c 12 Jan 2004 11:15:50 -0000 1.16
***************
*** 591,597 ****
buffer = xrealloc (buffer, bufmax);
}
buffer[buflen] = '\0';
! xgettext_comment_add (buffer);
}
--- 591,597 ----
buffer = xrealloc (buffer, bufmax);
}
buffer[buflen] = '\0';
! savable_comment_add (buffer);
}
***************
*** 721,726 ****
--- 721,728 ----
{
token_type_ty type;
char *string; /* for token_type_name,
token_type_string_literal */
+ refcounted_string_list_ty *comment; /* for token_type_string_literal,
+ token_type_objc_special */
long number;
int line_number;
};
***************
*** 883,888 ****
--- 885,893 ----
{
if (tp->type == token_type_name || tp->type == token_type_string_literal)
free (tp->string);
+ if (tp->type == token_type_string_literal
+ || tp->type == token_type_objc_special)
+ drop_reference (tp->comment);
}
***************
*** 1134,1139 ****
--- 1139,1145 ----
buffer[bufpos] = 0;
tp->type = token_type_string_literal;
tp->string = xstrdup (buffer);
+ tp->comment = add_reference (savable_comment);
return;
case '(':
***************
*** 1160,1165 ****
--- 1166,1172 ----
if (objc_extensions)
{
tp->type = token_type_objc_special;
+ tp->comment = add_reference (savable_comment);
return;
}
/* FALLTHROUGH */
***************
*** 1312,1318 ****
free_token (&buf[j]);
/* We must reset the selected comments. */
! xgettext_comment_reset ();
}
}
--- 1319,1325 ----
free_token (&buf[j]);
/* We must reset the selected comments. */
! savable_comment_reset ();
}
}
***************
*** 1387,1392 ****
--- 1394,1400 ----
new_string[len + 2] = '\0';
free (tp->string);
tp->string = new_string;
+ tp->comment = add_reference (savable_comment);
tp->type = token_type_string_literal;
}
}
***************
*** 1421,1427 ****
with non-white space tokens. */
++newline_count;
if (last_non_comment_line > last_comment_line)
! xgettext_comment_reset ();
continue;
}
break;
--- 1429,1435 ----
with non-white space tokens. */
++newline_count;
if (last_non_comment_line > last_comment_line)
! savable_comment_reset ();
continue;
}
break;
***************
*** 1453,1458 ****
--- 1461,1468 ----
return;
}
/* Drop the '@' token and return immediately the following string. */
+ drop_reference (tmp.comment);
+ tmp.comment = tp->comment;
*tp = tmp;
}
***************
*** 1523,1528 ****
--- 1533,1541 ----
xgettext_token_type_keyword, xgettext_token_type_symbol. */
char *string;
+ /* This field is used only for xgettext_token_type_string_literal. */
+ refcounted_string_list_ty *comment;
+
/* These fields are only for
xgettext_token_type_keyword,
xgettext_token_type_string_literal. */
***************
*** 1595,1604 ****
--- 1608,1622 ----
tp->type = xgettext_token_type_string_literal;
tp->string = token.string;
+ tp->comment = token.comment;
tp->pos.file_name = logical_file_name;
tp->pos.line_number = token.line_number;
return;
+ case token_type_objc_special:
+ drop_reference (token.comment);
+ /* FALLTHROUGH */
+
default:
last_non_comment_line = newline_count;
***************
*** 1761,1767 ****
case xgettext_token_type_string_literal:
if (extract_all)
! remember_a_message (mlp, token.string, inner_context, &token.pos);
else
{
if (commas_to_skip == 0)
--- 1779,1789 ----
case xgettext_token_type_string_literal:
if (extract_all)
! {
! savable_comment_to_xgettext_comment (token.comment);
! remember_a_message (mlp, token.string, inner_context, &token.pos);
! savable_comment_reset ();
! }
else
{
if (commas_to_skip == 0)
***************
*** 1769,1777 ****
if (plural_mp == NULL)
{
/* Seen an msgid. */
! message_ty *mp =
! remember_a_message (mlp, token.string,
! inner_context, &token.pos);
if (plural_commas > 0)
plural_mp = mp;
}
--- 1791,1802 ----
if (plural_mp == NULL)
{
/* Seen an msgid. */
! message_ty *mp;
!
! savable_comment_to_xgettext_comment (token.comment);
! mp = remember_a_message (mlp, token.string,
! inner_context, &token.pos);
! savable_comment_reset ();
if (plural_commas > 0)
plural_mp = mp;
}
***************
*** 1786,1791 ****
--- 1811,1817 ----
else
free (token.string);
}
+ drop_reference (token.comment);
next_context_iter = null_context_list_iterator;
selectorcall_context_iter = null_context_list_iterator;
state = 0;
*** gettext-tools/src/x-java.c 30 Dec 2003 11:33:18 -0000 1.10
--- gettext-tools/src/x-java.c 12 Jan 2004 11:15:50 -0000 1.11
***************
*** 572,670 ****
/* ======================== Accumulating comments. ========================
*/
- /* In this backend we cannot use the xgettext_comment* functions directly,
- because in multiline string expressions like
- "string1" +
- "string2"
- the newline between "string1" and "string2" would cause a call to
- xgettext_comment_reset(), thus destroying the accumulated comments
- that we need a little later, when we have concatenated the two strings
- and pass them to remember_a_message().
- Instead, we do the bookkeeping of the accumulated comments directly,
- and save a pointer to the accumulated comments when we read "string1".
- In order to avoid excessive copying of strings, we use reference
- counting. */
-
- typedef struct refcounted_string_list_ty refcounted_string_list_ty;
- struct refcounted_string_list_ty
- {
- unsigned int refcount;
- struct string_list_ty contents;
- };
-
- static refcounted_string_list_ty *comment;
-
- static inline refcounted_string_list_ty *
- add_reference (refcounted_string_list_ty *rslp)
- {
- if (rslp != NULL)
- rslp->refcount++;
- return rslp;
- }
-
- static inline void
- drop_reference (refcounted_string_list_ty *rslp)
- {
- if (rslp != NULL)
- {
- if (rslp->refcount > 1)
- rslp->refcount--;
- else
- {
- string_list_destroy (&rslp->contents);
- free (rslp);
- }
- }
- }
-
- static void
- x_java_comment_add (const char *str)
- {
- if (comment == NULL)
- {
- comment = (refcounted_string_list_ty *) xmalloc (sizeof (*comment));
- comment->refcount = 1;
- string_list_init (&comment->contents);
- }
- else if (comment->refcount > 1)
- {
- /* Unshare the list by making copies. */
- struct string_list_ty *oldcontents;
- size_t i;
-
- comment->refcount--;
- oldcontents = &comment->contents;
-
- comment = (refcounted_string_list_ty *) xmalloc (sizeof (*comment));
- comment->refcount = 1;
- string_list_init (&comment->contents);
- for (i = 0; i < oldcontents->nitems; i++)
- string_list_append (&comment->contents, oldcontents->item[i]);
- }
- string_list_append (&comment->contents, str);
- }
-
- static void
- x_java_comment_reset ()
- {
- drop_reference (comment);
- comment = NULL;
- }
-
- static void
- x_java_comment_to_xgettext_comment (refcounted_string_list_ty *rslp)
- {
- xgettext_comment_reset ();
- if (rslp != NULL)
- {
- size_t i;
-
- for (i = 0; i < rslp->contents.nitems; i++)
- xgettext_comment_add (rslp->contents.item[i]);
- }
- }
-
-
/* Accumulating a single comment line. */
static struct string_buffer comment_buffer;
--- 572,577 ----
***************
*** 701,707 ****
&& (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t'))
--buflen;
buffer[buflen] = '\0';
! x_java_comment_add (buffer);
}
--- 608,614 ----
&& (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t'))
--buflen;
buffer[buflen] = '\0';
! savable_comment_add (buffer);
}
***************
*** 963,969 ****
{
case '\n':
if (last_non_comment_line > last_comment_line)
! x_java_comment_reset ();
/* FALLTHROUGH */
case ' ':
case '\t':
--- 870,876 ----
{
case '\n':
if (last_non_comment_line > last_comment_line)
! savable_comment_reset ();
/* FALLTHROUGH */
case ' ':
case '\t':
***************
*** 1096,1102 ****
accumulate_escaped (&literal, '"');
tp->string = xstrdup (string_buffer_result (&literal));
free_string_buffer (&literal);
! tp->comment = add_reference (comment);
tp->type = token_type_string_literal;
return;
}
--- 1003,1009 ----
accumulate_escaped (&literal, '"');
tp->string = xstrdup (string_buffer_result (&literal));
free_string_buffer (&literal);
! tp->comment = add_reference (savable_comment);
tp->type = token_type_string_literal;
return;
}
***************
*** 1476,1484 ****
if (extract_all)
{
xgettext_current_source_encoding = po_charset_utf8;
! x_java_comment_to_xgettext_comment (token.comment);
remember_a_message (mlp, token.string, inner_context, &pos);
! x_java_comment_reset ();
xgettext_current_source_encoding =
xgettext_global_source_encoding;
}
else
--- 1383,1391 ----
if (extract_all)
{
xgettext_current_source_encoding = po_charset_utf8;
! savable_comment_to_xgettext_comment (token.comment);
remember_a_message (mlp, token.string, inner_context, &pos);
! savable_comment_reset ();
xgettext_current_source_encoding =
xgettext_global_source_encoding;
}
else
***************
*** 1491,1500 ****
message_ty *mp;
xgettext_current_source_encoding = po_charset_utf8;
! x_java_comment_to_xgettext_comment (token.comment);
mp = remember_a_message (mlp, token.string,
inner_context, &pos);
! x_java_comment_reset ();
xgettext_current_source_encoding =
xgettext_global_source_encoding;
if (plural_commas > 0)
plural_mp = mp;
--- 1398,1407 ----
message_ty *mp;
xgettext_current_source_encoding = po_charset_utf8;
! savable_comment_to_xgettext_comment (token.comment);
mp = remember_a_message (mlp, token.string,
inner_context, &pos);
! savable_comment_reset ();
xgettext_current_source_encoding =
xgettext_global_source_encoding;
if (plural_commas > 0)
plural_mp = mp;
*** gettext-tools/src/x-python.c 30 Dec 2003 11:33:18 -0000 1.14
--- gettext-tools/src/x-python.c 12 Jan 2004 11:15:50 -0000 1.15
***************
*** 240,246 ****
buffer = xrealloc (buffer, bufmax);
}
buffer[buflen] = '\0';
! xgettext_comment_add (buffer);
}
/* These are for tracking whether comments count as immediately before
--- 240,246 ----
buffer = xrealloc (buffer, bufmax);
}
buffer[buflen] = '\0';
! savable_comment_add (buffer);
}
/* These are for tracking whether comments count as immediately before
***************
*** 322,327 ****
--- 322,328 ----
{
token_type_ty type;
char *string; /* for token_type_string, token_type_symbol */
+ refcounted_string_list_ty *comment; /* for token_type_string */
int line_number;
};
***************
*** 696,702 ****
case '\n':
if (last_non_comment_line > last_comment_line)
! xgettext_comment_reset ();
/* Ignore newline if and only if it is used for implicit line
joining. */
if (open_pbb > 0)
--- 697,703 ----
case '\n':
if (last_non_comment_line > last_comment_line)
! savable_comment_reset ();
/* Ignore newline if and only if it is used for implicit line
joining. */
if (open_pbb > 0)
***************
*** 911,916 ****
--- 912,918 ----
assert (q - utf8_string <= 3 * bufpos);
tp->string = (char *) utf8_string;
}
+ tp->comment = add_reference (savable_comment);
tp->type = token_type_string;
return;
}
***************
*** 1121,1127 ****
pos.line_number = token.line_number;
if (extract_all)
! remember_a_message (mlp, token.string, inner_context, &pos);
else
{
if (commas_to_skip == 0)
--- 1123,1133 ----
pos.line_number = token.line_number;
if (extract_all)
! {
! savable_comment_to_xgettext_comment (token.comment);
! remember_a_message (mlp, token.string, inner_context, &pos);
! savable_comment_reset ();
! }
else
{
if (commas_to_skip == 0)
***************
*** 1129,1137 ****
if (plural_mp == NULL)
{
/* Seen an msgid. */
! message_ty *mp =
! remember_a_message (mlp, token.string,
! inner_context, &pos);
if (plural_commas > 0)
plural_mp = mp;
}
--- 1135,1146 ----
if (plural_mp == NULL)
{
/* Seen an msgid. */
! message_ty *mp;
!
! savable_comment_to_xgettext_comment (token.comment);
! mp = remember_a_message (mlp, token.string,
! inner_context, &pos);
! savable_comment_reset ();
if (plural_commas > 0)
plural_mp = mp;
}
***************
*** 1147,1152 ****
--- 1156,1162 ----
free (token.string);
}
}
+ drop_reference (token.comment);
next_context_iter = null_context_list_iterator;
state = 0;
continue;
*** gettext-tools/src/xgettext.c 6 Jan 2004 10:24:08 -0000 1.37
--- gettext-tools/src/xgettext.c 12 Jan 2004 11:15:50 -0000 1.38
***************
*** 1482,1487 ****
--- 1482,1539 ----
}
+ refcounted_string_list_ty *savable_comment;
+
+ void
+ savable_comment_add (const char *str)
+ {
+ if (savable_comment == NULL)
+ {
+ savable_comment =
+ (refcounted_string_list_ty *) xmalloc (sizeof (*savable_comment));
+ savable_comment->refcount = 1;
+ string_list_init (&savable_comment->contents);
+ }
+ else if (savable_comment->refcount > 1)
+ {
+ /* Unshare the list by making copies. */
+ struct string_list_ty *oldcontents;
+ size_t i;
+
+ savable_comment->refcount--;
+ oldcontents = &savable_comment->contents;
+
+ savable_comment =
+ (refcounted_string_list_ty *) xmalloc (sizeof (*savable_comment));
+ savable_comment->refcount = 1;
+ string_list_init (&savable_comment->contents);
+ for (i = 0; i < oldcontents->nitems; i++)
+ string_list_append (&savable_comment->contents, oldcontents->item[i]);
+ }
+ string_list_append (&savable_comment->contents, str);
+ }
+
+ void
+ savable_comment_reset ()
+ {
+ drop_reference (savable_comment);
+ savable_comment = NULL;
+ }
+
+ void
+ savable_comment_to_xgettext_comment (refcounted_string_list_ty *rslp)
+ {
+ xgettext_comment_reset ();
+ if (rslp != NULL)
+ {
+ size_t i;
+
+ for (i = 0; i < rslp->contents.nitems; i++)
+ xgettext_comment_add (rslp->contents.item[i]);
+ }
+ }
+
+
static FILE *
xgettext_open (const char *fn,
*** gettext-tools/src/xgettext.h 20 Oct 2003 20:31:45 -0000 1.6
--- gettext-tools/src/xgettext.h 12 Jan 2004 11:15:50 -0000 1.7
***************
*** 21,26 ****
--- 21,27 ----
#define _XGETTEXT_H
#include <stddef.h>
+ #include <stdlib.h>
#if HAVE_ICONV
#include <iconv.h>
***************
*** 28,33 ****
--- 29,35 ----
#include "message.h"
#include "pos.h"
+ #include "str-list.h"
/* Declare 'line_comment' and 'input_syntax'. */
#include "read-po.h"
***************
*** 144,149 ****
--- 146,202 ----
extern void xgettext_comment_add (const char *str);
extern const char *xgettext_comment (size_t n);
extern void xgettext_comment_reset (void);
+
+
+ /* Comment handling for backends which support combining adjacent strings
+ even across lines.
+ In these backends we cannot use the xgettext_comment* functions directly,
+ because in multiline string expressions like
+ "string1" +
+ "string2"
+ the newline between "string1" and "string2" would cause a call to
+ xgettext_comment_reset(), thus destroying the accumulated comments
+ that we need a little later, when we have concatenated the two strings
+ and pass them to remember_a_message().
+ Instead, we do the bookkeeping of the accumulated comments directly,
+ and save a pointer to the accumulated comments when we read "string1".
+ In order to avoid excessive copying of strings, we use reference
+ counting. */
+
+ typedef struct refcounted_string_list_ty refcounted_string_list_ty;
+ struct refcounted_string_list_ty
+ {
+ unsigned int refcount;
+ struct string_list_ty contents;
+ };
+
+ static inline refcounted_string_list_ty *
+ add_reference (refcounted_string_list_ty *rslp)
+ {
+ if (rslp != NULL)
+ rslp->refcount++;
+ return rslp;
+ }
+
+ static inline void
+ drop_reference (refcounted_string_list_ty *rslp)
+ {
+ if (rslp != NULL)
+ {
+ if (rslp->refcount > 1)
+ rslp->refcount--;
+ else
+ {
+ string_list_destroy (&rslp->contents);
+ free (rslp);
+ }
+ }
+ }
+
+ extern refcounted_string_list_ty *savable_comment;
+ extern void savable_comment_add (const char *str);
+ extern void savable_comment_reset (void);
+ extern void savable_comment_to_xgettext_comment (refcounted_string_list_ty
*rslp);
/* Add a message to the list of extracted messages.