]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Improved handling of multi-part strings when there is a newline between
authorBruno Haible <bruno@clisp.org>
Mon, 12 Jan 2004 11:15:50 +0000 (11:15 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:11:36 +0000 (12:11 +0200)
the parts of the string.

13 files changed:
gettext-tools/src/ChangeLog
gettext-tools/src/x-c.c
gettext-tools/src/x-csharp.c
gettext-tools/src/x-java.c
gettext-tools/src/x-python.c
gettext-tools/src/xgettext.c
gettext-tools/src/xgettext.h
gettext-tools/tests/ChangeLog
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-c-9
gettext-tools/tests/xgettext-csharp-5
gettext-tools/tests/xgettext-java-5
gettext-tools/tests/xgettext-python-2

index d76d157f40f127dc2827e76e839ce8c424ab558e..b0dbac29fb0f353ae3ab13ce487bcadd53060cfe 100644 (file)
@@ -1,3 +1,45 @@
+2003-12-29  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext.h: Include stdlib.h, str-list.h.
+       (struct refcounted_string_list_ty): New type.
+       (add_reference, drop_reference): New functions.
+       (savable_comment, savable_comment_add, savable_comment_reset,
+       savable_comment_to_xgettext_comment): New declarations.
+       * xgettext.c (savable_comment): New variable.
+       (savable_comment_add, savable_comment_reset,
+       savable_comment_to_xgettext_comment): New functions.
+       * x-java.c (struct refcounted_string_list_ty, comment, add_reference,
+       drop_reference, x_java_comment_add, x_java_comment_reset,
+       x_java_comment_to_xgettext_comment): Remove. Use replacement from
+       xgettext.{h,c} instead.
+       * x-csharp.c (struct refcounted_string_list_ty, comment, add_reference,
+       drop_reference, x_csharp_comment_add, x_csharp_comment_reset,
+       x_csharp_comment_to_xgettext_comment): Remove. Use replacement from
+       xgettext.{h,c} instead.
+       * x-c.c (comment_line_end): Call savable_comment_add instead of
+       xgettext_comment_add.
+       (struct token_ty): Add 'comment' field.
+       (free_token): Free it.
+       (phase5_get): Initialize token's 'comment' field.
+       (phase6_get): Call savable_comment_reset instead of
+       xgettext_comment_reset.
+       (phase8a_get): Initialize token's 'comment' field.
+       (phase8b_get): Call savable_comment_reset instead of
+       xgettext_comment_reset.
+       (phase8c_get): In @"...", use the comment of the first token, not of
+       the second.
+       (struct xgettext_token_ty): Add 'comment' field.
+       (x_c_lex): Deal with the token's comment.
+       (extract_parenthesized): Call savable_comment_to_xgettext_comment and
+       savable_comment_reset. Free the token's comment field.
+       * x-python.c (comment_line_end): Call savable_comment_add instead of
+       xgettext_comment_add.
+       (struct token_ty): Add 'comment' field.
+       (phase5_get): Call savable_comment_reset instead of
+       xgettext_comment_reset. Initialize token's 'comment' field.
+       (extract_parenthesized): Call savable_comment_to_xgettext_comment and
+       savable_comment_reset. Free the token's comment field.
+
 2003-12-28  Bruno Haible  <bruno@clisp.org>
 
        * read-mo.h (read_mo_file): Change 'fn' into 'filename'.
index 52a79ceeb97cbc98025751ef8da27a52a3a041c1..93a390f8c7b75c2665d3fea6b03dd0cb9e9f6a72 100644 (file)
@@ -591,7 +591,7 @@ comment_line_end (size_t chars_to_remove)
       buffer = xrealloc (buffer, bufmax);
     }
   buffer[buflen] = '\0';
-  xgettext_comment_add (buffer);
+  savable_comment_add (buffer);
 }
 
 
@@ -721,6 +721,8 @@ struct token_ty
 {
   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,6 +885,9 @@ free_token (token_ty *tp)
 {
   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,6 +1139,7 @@ phase5_get (token_ty *tp)
       buffer[bufpos] = 0;
       tp->type = token_type_string_literal;
       tp->string = xstrdup (buffer);
+      tp->comment = add_reference (savable_comment);
       return;
 
     case '(':
@@ -1160,6 +1166,7 @@ phase5_get (token_ty *tp)
       if (objc_extensions)
        {
          tp->type = token_type_objc_special;
+         tp->comment = add_reference (savable_comment);
          return;
        }
       /* FALLTHROUGH */
@@ -1312,7 +1319,7 @@ phase6_get (token_ty *tp)
        free_token (&buf[j]);
 
       /* We must reset the selected comments.  */
-      xgettext_comment_reset ();
+      savable_comment_reset ();
     }
 }
 
@@ -1387,6 +1394,7 @@ phase8a_get (token_ty *tp)
       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,7 +1429,7 @@ phase8b_get (token_ty *tp)
             with non-white space tokens.  */
          ++newline_count;
          if (last_non_comment_line > last_comment_line)
-           xgettext_comment_reset ();
+           savable_comment_reset ();
          continue;
        }
       break;
@@ -1453,6 +1461,8 @@ phase8c_get (token_ty *tp)
       return;
     }
   /* Drop the '@' token and return immediately the following string.  */
+  drop_reference (tmp.comment);
+  tmp.comment = tp->comment;
   *tp = tmp;
 }
 
@@ -1523,6 +1533,9 @@ struct xgettext_token_ty
      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,10 +1608,15 @@ x_c_lex (xgettext_token_ty *tp)
 
          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,7 +1779,11 @@ extract_parenthesized (message_list_ty *mlp,
 
        case xgettext_token_type_string_literal:
          if (extract_all)
-           remember_a_message (mlp, token.string, inner_context, &token.pos);
+           {
+             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,9 +1791,12 @@ extract_parenthesized (message_list_ty *mlp,
                  if (plural_mp == NULL)
                    {
                      /* Seen an msgid.  */
-                     message_ty *mp =
-                       remember_a_message (mlp, token.string,
-                                           inner_context, &token.pos);
+                     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,6 +1811,7 @@ extract_parenthesized (message_list_ty *mlp,
              else
                free (token.string);
            }
+         drop_reference (token.comment);
          next_context_iter = null_context_list_iterator;
          selectorcall_context_iter = null_context_list_iterator;
          state = 0;
index 150facdbdf1a58f3276de1eb01b156480c48e5a3..4dd27e467edf555e7fd613d52e7ec63a55f597e3 100644 (file)
@@ -580,99 +580,6 @@ free_string_buffer (struct string_buffer *bp)
 /* ======================== 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_csharp_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_csharp_comment_reset ()
-{
-  drop_reference (comment);
-  comment = NULL;
-}
-
-static void
-x_csharp_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;
@@ -706,7 +613,7 @@ comment_line_end (size_t chars_to_remove)
         && (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t'))
     --buflen;
   buffer[buflen] = '\0';
-  x_csharp_comment_add (buffer);
+  savable_comment_add (buffer);
 }
 
 
@@ -1637,7 +1544,7 @@ phase6_get (token_ty *tp)
        {
        case UNL:
          if (last_non_comment_line > last_comment_line)
-           x_csharp_comment_reset ();
+           savable_comment_reset ();
          /* FALLTHROUGH */
        case ' ':
        case '\t':
@@ -1725,7 +1632,7 @@ phase6_get (token_ty *tp)
            accumulate_escaped (&literal, '"');
            tp->string = xstrdup (string_buffer_result (&literal));
            free_string_buffer (&literal);
-           tp->comment = add_reference (comment);
+           tp->comment = add_reference (savable_comment);
            tp->type = token_type_string_literal;
            return;
          }
@@ -1787,7 +1694,7 @@ phase6_get (token_ty *tp)
                }
              tp->string = xstrdup (string_buffer_result (&literal));
              free_string_buffer (&literal);
-             tp->comment = add_reference (comment);
+             tp->comment = add_reference (savable_comment);
              tp->type = token_type_string_literal;
              return;
            }
@@ -2158,9 +2065,9 @@ extract_parenthesized (message_list_ty *mlp, token_type_ty terminator,
            if (extract_all)
              {
                xgettext_current_source_encoding = po_charset_utf8;
-               x_csharp_comment_to_xgettext_comment (token.comment);
+               savable_comment_to_xgettext_comment (token.comment);
                remember_a_message (mlp, token.string, inner_context, &pos);
-               x_csharp_comment_reset ();
+               savable_comment_reset ();
                xgettext_current_source_encoding = xgettext_global_source_encoding;
              }
            else
@@ -2173,10 +2080,10 @@ extract_parenthesized (message_list_ty *mlp, token_type_ty terminator,
                        message_ty *mp;
 
                        xgettext_current_source_encoding = po_charset_utf8;
-                       x_csharp_comment_to_xgettext_comment (token.comment);
+                       savable_comment_to_xgettext_comment (token.comment);
                        mp = remember_a_message (mlp, token.string,
                                                 inner_context, &pos);
-                       x_csharp_comment_reset ();
+                       savable_comment_reset ();
                        xgettext_current_source_encoding = xgettext_global_source_encoding;
                        if (plural_commas > 0)
                          plural_mp = mp;
index 8bb0545e9eb0434bed5fdf36775929b0980928d4..821cca3d2af40c9facc07169df62189a1725f7d0 100644 (file)
@@ -572,99 +572,6 @@ free_string_buffer (struct string_buffer *bp)
 /* ======================== 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;
@@ -701,7 +608,7 @@ comment_line_end (size_t chars_to_remove)
         && (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t'))
     --buflen;
   buffer[buflen] = '\0';
-  x_java_comment_add (buffer);
+  savable_comment_add (buffer);
 }
 
 
@@ -963,7 +870,7 @@ phase5_get (token_ty *tp)
        {
        case '\n':
          if (last_non_comment_line > last_comment_line)
-           x_java_comment_reset ();
+           savable_comment_reset ();
          /* FALLTHROUGH */
        case ' ':
        case '\t':
@@ -1096,7 +1003,7 @@ phase5_get (token_ty *tp)
            accumulate_escaped (&literal, '"');
            tp->string = xstrdup (string_buffer_result (&literal));
            free_string_buffer (&literal);
-           tp->comment = add_reference (comment);
+           tp->comment = add_reference (savable_comment);
            tp->type = token_type_string_literal;
            return;
          }
@@ -1476,9 +1383,9 @@ extract_parenthesized (message_list_ty *mlp, token_type_ty terminator,
            if (extract_all)
              {
                xgettext_current_source_encoding = po_charset_utf8;
-               x_java_comment_to_xgettext_comment (token.comment);
+               savable_comment_to_xgettext_comment (token.comment);
                remember_a_message (mlp, token.string, inner_context, &pos);
-               x_java_comment_reset ();
+               savable_comment_reset ();
                xgettext_current_source_encoding = xgettext_global_source_encoding;
              }
            else
@@ -1491,10 +1398,10 @@ extract_parenthesized (message_list_ty *mlp, token_type_ty terminator,
                        message_ty *mp;
 
                        xgettext_current_source_encoding = po_charset_utf8;
-                       x_java_comment_to_xgettext_comment (token.comment);
+                       savable_comment_to_xgettext_comment (token.comment);
                        mp = remember_a_message (mlp, token.string,
                                                 inner_context, &pos);
-                       x_java_comment_reset ();
+                       savable_comment_reset ();
                        xgettext_current_source_encoding = xgettext_global_source_encoding;
                        if (plural_commas > 0)
                          plural_mp = mp;
index 3e2ced7a4022847e830a124e0747b80a9e4a5f55..d2b6a85ac28d98d0e3ca0294f35d65e06835b13f 100644 (file)
@@ -240,7 +240,7 @@ comment_line_end ()
       buffer = xrealloc (buffer, bufmax);
     }
   buffer[buflen] = '\0';
-  xgettext_comment_add (buffer);
+  savable_comment_add (buffer);
 }
 
 /* These are for tracking whether comments count as immediately before
@@ -322,6 +322,7 @@ struct token_ty
 {
   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,7 +697,7 @@ phase5_get (token_ty *tp)
 
        case '\n':
          if (last_non_comment_line > last_comment_line)
-           xgettext_comment_reset ();
+           savable_comment_reset ();
          /* Ignore newline if and only if it is used for implicit line
             joining.  */
          if (open_pbb > 0)
@@ -911,6 +912,7 @@ phase5_get (token_ty *tp)
                assert (q - utf8_string <= 3 * bufpos);
                tp->string = (char *) utf8_string;
              }
+             tp->comment = add_reference (savable_comment);
              tp->type = token_type_string;
              return;
          }
@@ -1121,7 +1123,11 @@ extract_parenthesized (message_list_ty *mlp,
            pos.line_number = token.line_number;
 
            if (extract_all)
-             remember_a_message (mlp, token.string, inner_context, &pos);
+             {
+               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,9 +1135,12 @@ extract_parenthesized (message_list_ty *mlp,
                    if (plural_mp == NULL)
                      {
                        /* Seen an msgid.  */
-                       message_ty *mp =
-                         remember_a_message (mlp, token.string,
-                                             inner_context, &pos);
+                       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,6 +1156,7 @@ extract_parenthesized (message_list_ty *mlp,
                  free (token.string);
              }
          }
+         drop_reference (token.comment);
          next_context_iter = null_context_list_iterator;
          state = 0;
          continue;
index 5c5a39554bc7f507cf93d925934f44eb9a8e68e7..cde60b5357695747995b8acd87dbcf38e7c515d8 100644 (file)
@@ -1482,6 +1482,58 @@ xgettext_comment_reset ()
 }
 
 
+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,
index ba1f9142587bd9fc14fdb9b050c6e3893b32a7e0..86bf1c10f2a4563e6d704bcc46f293075bd7044b 100644 (file)
@@ -21,6 +21,7 @@
 #define _XGETTEXT_H
 
 #include <stddef.h>
+#include <stdlib.h>
 
 #if HAVE_ICONV
 #include <iconv.h>
@@ -28,6 +29,7 @@
 
 #include "message.h"
 #include "pos.h"
+#include "str-list.h"
 
 /* Declare 'line_comment' and 'input_syntax'.  */
 #include "read-po.h"
@@ -146,6 +148,57 @@ 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.
    string must be malloc()ed string; its ownership is passed to the callee.
    pos->file_name must be allocated with indefinite extent.  */
index f257445b18e30e21cca003aad1f0d3e7c80d1d12..478a4f4462271288f04001bf5262c1a865970362 100644 (file)
@@ -1,3 +1,13 @@
+2003-12-29  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext-c-9: Add a test with a multi-part string with newlines and
+       comments between the parts.
+       * xgettext-java-5: Likewise.
+       * xgettext-csharp-5: Likewise.
+       * xgettext-python-2: Likewise.
+       * xgettext-objc-2: New file.
+       * Makefile.am (TESTS): Add it.
+
 2003-12-26  Bruno Haible  <bruno@clisp.org>
 
        Support for C#.
index 4859c6f2fbdd8247ee066acd1669fdbc9c34e66e..8015ace4216620094113868bb21f4e62e0e5cbcb 100644 (file)
@@ -69,7 +69,7 @@ TESTS = gettext-1 gettext-2 \
        xgettext-java-5 \
        xgettext-librep-1 \
        xgettext-lisp-1 \
-       xgettext-objc-1 \
+       xgettext-objc-1 xgettext-objc-2 \
        xgettext-perl-1 xgettext-perl-2 xgettext-perl-3 xgettext-perl-4 \
        xgettext-perl-5 \
        xgettext-php-1 \
index b09095409a33d6a08e3ad6b75e67f4c07d1fca49..43e7e5929a488b83f469b9df422b070bad80a029 100755 (executable)
@@ -17,6 +17,10 @@ print (gettext ("Hey Jude"));
      Nickname of the Beatles
 */
 print (gettext ("The Fabulous Four"));
+/* TRANSLATORS: The strings get concatenated.  */
+print (gettext ("there is not enough"
+" room on a single line for this entire long, " // confusing, eh?
+"verbose string"));
 EOF
 
 tmpfiles="$tmpfiles xg-c-9.po"
@@ -42,6 +46,12 @@ msgstr ""
 #.
 msgid "The Fabulous Four"
 msgstr ""
+
+#. TRANSLATORS: The strings get concatenated.
+msgid ""
+"there is not enough room on a single line for this entire long, verbose "
+"string"
+msgstr ""
 EOF
 
 : ${DIFF=diff}
index a9a525d2220031a902cad24501c2d0b208917749..03e4b15272e18106a97a21e91935622c4c1b9109 100755 (executable)
@@ -17,6 +17,10 @@ Console.WriteLine(GetString("Hey Jude"));
      Nickname of the Beatles
 */
 Console.WriteLine(GetString("The Fabulous Four"));
+/* TRANSLATORS: The strings get concatenated.  */
+Console.WriteLine(GetString("there is not enough" +
+" room on a single line for this entire long, " // confusing, eh?
++ "verbose string"));
 EOF
 
 tmpfiles="$tmpfiles xg-cs-5.po"
@@ -42,6 +46,12 @@ msgstr ""
 #.
 msgid "The Fabulous Four"
 msgstr ""
+
+#. TRANSLATORS: The strings get concatenated.
+msgid ""
+"there is not enough room on a single line for this entire long, verbose "
+"string"
+msgstr ""
 EOF
 
 : ${DIFF=diff}
index 0d77a50c380d915d51658d63a9b4ce2dd146fcc8..6b8307db164ec71b7e4aea6da7d2b573a553fad8 100755 (executable)
@@ -17,6 +17,10 @@ System.out.println(gettext("Hey Jude"));
      Nickname of the Beatles
 */
 System.out.println(gettext("The Fabulous Four"));
+/* TRANSLATORS: The strings get concatenated.  */
+System.out.println(gettext("there is not enough" +
+" room on a single line for this entire long, " // confusing, eh?
++ "verbose string"));
 EOF
 
 tmpfiles="$tmpfiles xg-j-5.po"
@@ -42,6 +46,12 @@ msgstr ""
 #.
 msgid "The Fabulous Four"
 msgstr ""
+
+#. TRANSLATORS: The strings get concatenated.
+msgid ""
+"there is not enough room on a single line for this entire long, verbose "
+"string"
+msgstr ""
 EOF
 
 : ${DIFF=diff}
index 22518b722eb4d4a2289600c2d9ae7cc7b6e2e2ec..88d9b9d5b20437c8e2efb85ec9d416d0626456ba 100755 (executable)
@@ -16,6 +16,10 @@ print gettext.gettext("Hey Jude")
 # TRANSLATORS:
 #    Nickname of the Beatles
 print gettext.gettext("The Fabulous Four")
+# TRANSLATORS: The strings get concatenated.
+print gettext.gettext("there is not enough"
+" room on a single line for this entire long, " # confusing, eh?
+"verbose string")
 EOF
 
 tmpfiles="$tmpfiles xg-py-2.po"
@@ -40,6 +44,12 @@ msgstr ""
 #. Nickname of the Beatles
 msgid "The Fabulous Four"
 msgstr ""
+
+#. TRANSLATORS: The strings get concatenated.
+msgid ""
+"there is not enough room on a single line for this entire long, verbose "
+"string"
+msgstr ""
 EOF
 
 : ${DIFF=diff}