]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Fix result for concatenation of strings with escape sequences.
authorBruno Haible <bruno@clisp.org>
Sun, 4 Nov 2018 19:09:47 +0000 (20:09 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 4 Nov 2018 23:25:33 +0000 (00:25 +0100)
Reported by Morten Welinder <mwelinder@gmail.com>
in <https://lists.gnu.org/archive/html/bug-gettext/2015-12/msg00017.html>
and <https://savannah.gnu.org/bugs/?46756>.

Revert commits from
2014-05-07 xgettext: Provide a way to interpret string literals lazily
2014-05-07 c: Interpret string literals lazily
2014-05-09 vala: Interpret string literals lazily
2014-12-02 c: Support C++11 string literals
and subsequent fixes of these.

* gettext-tools/src/xgettext.h (savable_comment_convert_encoding): Remove
declaration.
(enum literalstring_escape_type, struct literalstring_parser): Remove types.
(struct partial_call): Update.
(arglist_parser_remember_literal): Remove declaration.
* gettext-tools/src/xgettext.c (struct extractor_ty): Remove
'literalstring_parser' field.
(savable_comment_convert_encoding): Remove function.
(current_literalstring_parser): Remove variable.
(extract_from_file, arglist_parser_alloc, arglist_parser_clone): Update.
(arglist_parser_remember_literal): Remove function.
(arglist_parser_remember_msgctxt): Simplify accordingly.
* gettext-tools/src/x-*.h (SCANNERS_*): Remove literalstring_parser initializer.
* gettext-tools/src/x-c.h (literalstring_c): Remove declaration.
* gettext-tools/src/x-c.c: Remove all traces of literalstring_escape_type and
literalstring_parser.
(phase7_getc, phase7_ungetc): Reinstantiate functions.
(phase5_get): Simplify. Use phase7_getc.
* gettext-tools/src/x-vala.c: Remove all traces of literalstring_escape_type and
literalstring_parser.
(phase7_getc, phase7_ungetc): Reinstantiate functions.
(phase3_get): Simplify. Use phase7_getc.
(extract_balanced): Simplify.

30 files changed:
gettext-tools/src/x-appdata.h
gettext-tools/src/x-awk.h
gettext-tools/src/x-c.c
gettext-tools/src/x-c.h
gettext-tools/src/x-csharp.h
gettext-tools/src/x-desktop.h
gettext-tools/src/x-elisp.h
gettext-tools/src/x-glade.h
gettext-tools/src/x-gsettings.h
gettext-tools/src/x-java.h
gettext-tools/src/x-javascript.h
gettext-tools/src/x-librep.h
gettext-tools/src/x-lisp.h
gettext-tools/src/x-lua.h
gettext-tools/src/x-perl.h
gettext-tools/src/x-php.h
gettext-tools/src/x-po.h
gettext-tools/src/x-properties.h
gettext-tools/src/x-python.h
gettext-tools/src/x-rst.h
gettext-tools/src/x-scheme.h
gettext-tools/src/x-sh.h
gettext-tools/src/x-smalltalk.h
gettext-tools/src/x-stringtable.h
gettext-tools/src/x-tcl.h
gettext-tools/src/x-vala.c
gettext-tools/src/x-vala.h
gettext-tools/src/x-ycp.h
gettext-tools/src/xgettext.c
gettext-tools/src/xgettext.h

index f020337de1e59bf1922b4ee846d98011e64774ff..6b18992ec72cf49a5a72b861bf093e558bc2178a 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext AppData file backend.
-   Copyright (C) 2002-2003, 2006, 2013, 2015-2017 Free Software Foundation,
-   Inc.
+   Copyright (C) 2002-2003, 2006, 2013, 2015-2017 Free Software Foundation, Inc.
    Written by Philip Withnall <philip.withnall@collabora.co.uk>, 2015.
 
    This program is free software: you can redistribute it and/or modify
index 62b53f7e96f1a61553fc66d4784fea3dac590c8f..f818d5582919c033cad3154cbc2148243be7cffe 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext awk backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2014-2015, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -34,7 +34,7 @@ extern "C" {
 
 #define SCANNERS_AWK \
   { "awk",              extract_awk,                                    \
-                        &flag_table_awk, &formatstring_awk, NULL, NULL }, \
+                        &flag_table_awk, &formatstring_awk, NULL },     \
 
 /* Scan an awk file and add its translatable strings to mdlp.  */
 extern void extract_awk (FILE *fp, const char *real_filename,
index ec3948d4a0d0944c60349b6922df1dca8aa3294e..1b81dfd5f5bfc80ea35783c59a6aeeabd47ed6b6 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext C/C++/ObjectiveC backend.
-   Copyright (C) 1995-1998, 2000-2009, 2012, 2015-2016, 2018 Free Software
-   Foundation, Inc.
+   Copyright (C) 1995-1998, 2000-2009, 2012-2015, 2018 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -955,243 +954,232 @@ struct token_ty
   char *string;         /* for token_type_name, token_type_string_literal */
   refcounted_string_list_ty *comment;   /* for token_type_string_literal,
                                            token_type_objc_special */
-  enum literalstring_escape_type escape; /* for token_type_string_literal */
   long number;
   int line_number;
 };
 
 
-/* Free the memory pointed to by a 'struct token_ty'.  */
-static inline void
-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);
-}
+/* 7. Replace escape sequences within character strings with their
+   single character equivalents.  This is called from phase 5, because
+   we don't have to worry about the #include argument.  There are
+   pathological cases which could bite us (like the DOS directory
+   separator), but just pretend it can't happen.  */
 
+/* Return value of phase7_getc when EOF is reached.  */
+#define P7_EOF (-1)
+#define P7_STRING_END (-2)
 
-static char *
-literalstring_parse (const char *string, lex_pos_ty *pos,
-                     enum literalstring_escape_type type)
-{
-  struct mixed_string_buffer *bp;
-  const char *p;
+/* Replace escape sequences within character strings with their single
+   character equivalents.  */
+#define P7_QUOTES (-3)
+#define P7_QUOTE (-4)
+#define P7_NEWLINE (-5)
 
-  /* Start accumulating the string.  */
-  bp = mixed_string_buffer_alloc (lc_string,
-                                  logical_file_name,
-                                  line_number);
+/* Convert an UTF-16 or UTF-32 code point to a return value that can be
+   distinguished from a single-byte return value.  */
+#define UNICODE(code) (0x100 + (code))
 
-  for (p = string; ; )
-    {
-      int c = *p++;
+/* Test a return value of phase7_getuc whether it designates an UTF-16 or
+   UTF-32 code point.  */
+#define IS_UNICODE(p7_result) ((p7_result) >= 0x100)
 
-      if (c == '\0')
-        break;
+/* Extract the UTF-16 or UTF-32 code of a return value that satisfies
+   IS_UNICODE.  */
+#define UNICODE_VALUE(p7_result) ((p7_result) - 0x100)
 
-      if (c != '\\')
-        {
-          mixed_string_buffer_append_char (bp, c);
-          continue;
-        }
 
-      if (!(type & LET_ANSI_C) && !(type & LET_UNICODE))
-        {
-          mixed_string_buffer_append_char (bp, '\\');
-          continue;
-        }
+static int
+phase7_getc ()
+{
+  int c, n, j;
 
-      c = *p++;
-      if (c == '\0')
-        break;
+  /* Use phase 3, because phase 4 elides comments.  */
+  c = phase3_getc ();
 
-      if (type & LET_ANSI_C)
-        switch (c)
-          {
-          case '"':
-          case '\'':
-          case '?':
-          case '\\':
-            mixed_string_buffer_append_char (bp, c);
-            continue;
-
-          case 'a':
-            mixed_string_buffer_append_char (bp, '\a');
-            continue;
-          case 'b':
-            mixed_string_buffer_append_char (bp, '\b');
-            continue;
-
-            /* The \e escape is preculiar to gcc, and assumes an ASCII
-               character set (or superset).  We don't provide support for it
-               here.  */
-
-          case 'f':
-            mixed_string_buffer_append_char (bp, '\f');
-            continue;
-          case 'n':
-            mixed_string_buffer_append_char (bp, '\n');
-            continue;
-          case 'r':
-            mixed_string_buffer_append_char (bp, '\r');
-            continue;
-          case 't':
-            mixed_string_buffer_append_char (bp, '\t');
-            continue;
-          case 'v':
-            mixed_string_buffer_append_char (bp, '\v');
-            continue;
-
-          case 'x':
-            c = *p++;
-            if (c == '\0')
-              break;
-            switch (c)
-              {
-              default:
-                mixed_string_buffer_append_char (bp, '\\');
-                mixed_string_buffer_append_char (bp, 'x');
-                mixed_string_buffer_append_char (bp, c);
-                break;
+  /* Return a magic newline indicator, so that we can distinguish
+     between the user requesting a newline in the string (e.g. using
+     "\n" or "\012") from the user failing to terminate the string or
+     character constant.  The ANSI C standard says: 3.1.3.4 Character
+     Constants contain "any character except single quote, backslash or
+     newline; or an escape sequence" and 3.1.4 String Literals contain
+     "any character except double quote, backslash or newline; or an
+     escape sequence".
+
+     Most compilers give a fatal error in this case, however gcc is
+     stupidly silent, even though this is a very common typo.  OK, so
+     "gcc --pedantic" will tell me, but that gripes about too much other
+     stuff.  Could I have a "gcc -Wnewline-in-string" option, or
+     better yet a "gcc -fno-newline-in-string" option, please?  Gcc is
+     also inconsistent between string literals and character constants:
+     you may not embed newlines in character constants; try it, you get
+     a useful diagnostic.  --PMiller  */
+  if (c == '\n')
+    return P7_NEWLINE;
+
+  if (c == '"')
+    return P7_QUOTES;
+  if (c == '\'')
+    return P7_QUOTE;
+  if (c != '\\')
+    return c;
+  c = phase3_getc ();
+  switch (c)
+    {
+    default:
+      /* Unknown escape sequences really should be an error, but just
+         ignore them, and let the real compiler complain.  */
+      phase3_ungetc (c);
+      return '\\';
 
-              case '0': case '1': case '2': case '3': case '4':
-              case '5': case '6': case '7': case '8': case '9':
-              case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-              case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-                {
-                  int n;
+    case '"':
+    case '\'':
+    case '?':
+    case '\\':
+      return c;
 
-                  for (n = 0; ; c = *p++)
-                    {
-                      switch (c)
-                        {
-                        default:
-                          break;
-
-                        case '0': case '1': case '2': case '3': case '4':
-                        case '5': case '6': case '7': case '8': case '9':
-                          n = n * 16 + c - '0';
-                          continue;
-
-                        case 'A': case 'B': case 'C': case 'D': case 'E':
-                        case 'F':
-                          n = n * 16 + 10 + c - 'A';
-                          continue;
-
-                        case 'a': case 'b': case 'c': case 'd': case 'e':
-                        case 'f':
-                          n = n * 16 + 10 + c - 'a';
-                          continue;
-                        }
-                      break;
-                    }
+    case 'a':
+      return '\a';
+    case 'b':
+      return '\b';
 
-                  mixed_string_buffer_append_char (bp, n);
-                  --p;
-                }
-                break;
-              }
-            continue;
+      /* The \e escape is preculiar to gcc, and assumes an ASCII
+         character set (or superset).  We don't provide support for it
+         here.  */
 
-          case '0': case '1': case '2': case '3':
-          case '4': case '5': case '6': case '7':
+    case 'f':
+      return '\f';
+    case 'n':
+      return '\n';
+    case 'r':
+      return '\r';
+    case 't':
+      return '\t';
+    case 'v':
+      return '\v';
+
+    case 'x':
+      c = phase3_getc ();
+      switch (c)
+        {
+        default:
+          phase3_ungetc (c);
+          phase3_ungetc ('x');
+          return '\\';
+
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+          break;
+        }
+      n = 0;
+      for (;;)
+        {
+          switch (c)
             {
-              int n, j;
+            default:
+              phase3_ungetc (c);
+              return n;
 
-              for (n = 0, j = 0; j < 3; ++j)
-                {
-                  n = n * 8 + c - '0';
-                  c = *p++;
-                  switch (c)
-                    {
-                    default:
-                      break;
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+              n = n * 16 + c - '0';
+              break;
 
-                    case '0': case '1': case '2': case '3':
-                    case '4': case '5': case '6': case '7':
-                      continue;
-                    }
-                  break;
-                }
+            case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+              n = n * 16 + 10 + c - 'A';
+              break;
 
-              mixed_string_buffer_append_char (bp, n);
-              --p;
+            case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+              n = n * 16 + 10 + c - 'a';
+              break;
             }
-            continue;
-          }
+          c = phase3_getc ();
+        }
+      return n;
 
-      if (type & LET_UNICODE)
-        switch (c)
-          {
-          case 'U': case 'u':
+    case '0': case '1': case '2': case '3':
+    case '4': case '5': case '6': case '7':
+      n = 0;
+      for (j = 0; j < 3; ++j)
+        {
+          n = n * 8 + c - '0';
+          c = phase3_getc ();
+          switch (c)
             {
-              unsigned char buf[8];
-              int prefix = c;
-              int length = prefix == 'u' ? 4 : 8;
-              int n, j;
-
-              for (n = 0, j = 0; j < length; j++)
-                {
-                  c = *p++;
-
-                  if (c >= '0' && c <= '9')
-                    n = (n << 4) + (c - '0');
-                  else if (c >= 'A' && c <= 'F')
-                    n = (n << 4) + (c - 'A' + 10);
-                  else if (c >= 'a' && c <= 'f')
-                    n = (n << 4) + (c - 'a' + 10);
-                  else
-                    break;
-
-                  buf[j] = c;
-                }
+            default:
+              break;
 
-              if (j == length)
-                {
-                  if (n < 0x110000)
-                    mixed_string_buffer_append_unicode (bp, n);
-                  else
-                    {
-                      error_with_progname = false;
-                      error_at_line (0, 0,
-                                     pos->file_name, pos->line_number,
-                                     _("\
-warning: invalid Unicode character"));
-                      error_with_progname = true;
-                    }
-                }
-              else
-                {
-                  int i;
+            case '0': case '1': case '2': case '3':
+            case '4': case '5': case '6': case '7':
+              continue;
+            }
+          break;
+        }
+      phase3_ungetc (c);
+      return n;
 
-                  mixed_string_buffer_append_char (bp, '\\');
-                  mixed_string_buffer_append_char (bp, prefix);
+    case 'U': case 'u':
+      {
+        unsigned char buf[8];
 
-                  for (i = 0; i < j; i++)
-                    mixed_string_buffer_append_char (bp, buf[i]);
+        n = 0;
+        for (j = 0; j < (c == 'u' ? 4 : 8); j++)
+          {
+            int c1 = phase3_getc ();
+
+            if (c1 >= '0' && c1 <= '9')
+              n = (n << 4) + (c1 - '0');
+            else if (c1 >= 'A' && c1 <= 'F')
+              n = (n << 4) + (c1 - 'A' + 10);
+            else if (c1 >= 'a' && c1 <= 'f')
+              n = (n << 4) + (c1 - 'a' + 10);
+            else
+              {
+                phase3_ungetc (c1);
+                while (--j >= 0)
+                  phase3_ungetc (buf[j]);
+                phase3_ungetc (c);
+                return '\\';
+              }
 
-                  --p;
-                }
-            }
-            continue;
+            buf[j] = c1;
           }
 
-      if (c == '\0')
-        break;
+        if (n < 0x110000)
+          return UNICODE (n);
+
+        error_with_progname = false;
+        error (0, 0, _("%s:%d: warning: invalid Unicode character"),
+               logical_file_name, line_number);
+        error_with_progname = true;
 
-      mixed_string_buffer_append_char (bp, c);
+        while (--j >= 0)
+          phase3_ungetc (buf[j]);
+        phase3_ungetc (c);
+        return '\\';
+      }
     }
+}
+
 
-  return mixed_string_buffer_done (bp);
+static void
+phase7_ungetc (int c)
+{
+  phase3_ungetc (c);
 }
 
-struct literalstring_parser literalstring_c =
-  {
-    literalstring_parse
-  };
+
+/* Free the memory pointed to by a 'struct token_ty'.  */
+static inline void
+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);
+}
 
 
 /* 5. Parse each resulting logical line as preprocessing tokens and
@@ -1208,11 +1196,6 @@ phase5_get (token_ty *tp)
   static int bufmax;
   int bufpos;
   int c;
-  int last_was_backslash;
-  bool raw_expected = false;
-  int delimiter_left_end;
-  int delimiter_right_start;
-  int last_rparen;
 
   if (phase5_pushback_length)
     {
@@ -1292,68 +1275,6 @@ phase5_get (token_ty *tp)
               continue;
 
             default:
-              /* Recognize string literals prefixed by R, u8, u8R, u,
-                 uR, U, UR, L, or LR.  It is defined in the C standard
-                 ISO/IEC 9899:201x and the C++ standard ISO/IEC
-                 14882:2011.  The raw string literals prefixed by R,
-                 u8R, uR, UR, or LR are only valid in C++.
-
-                 Since gettext's argument is a byte sequence, we are
-                 only interested in u8, R, and u8R.  */
-              if (c == '"')
-                {
-                  bool is_prefix = false;
-
-                  switch (buffer[0])
-                    {
-                    case 'R':
-                      if (cxx_extensions && bufpos == 1)
-                        {
-                          is_prefix = true;
-                          raw_expected = true;
-                        }
-                      break;
-                    case 'u':
-                      if (bufpos == 1)
-                        is_prefix = true;
-                      else
-                        switch (buffer[1])
-                          {
-                          case 'R':
-                            if (cxx_extensions && bufpos == 2)
-                              {
-                                is_prefix = true;
-                                raw_expected = true;
-                              }
-                            break;
-                          case '8':
-                            if (bufpos == 2)
-                              is_prefix = true;
-                            else if (cxx_extensions
-                                     && bufpos == 3 && buffer[2] == 'R')
-                              {
-                                is_prefix = true;
-                                raw_expected = true;
-                              }
-                            break;
-                          }
-                      break;
-                    case 'U':
-                    case 'L':
-                      if (bufpos == 1)
-                        is_prefix = true;
-                      else if (cxx_extensions
-                               && bufpos == 2 && buffer[1] == 'R')
-                        {
-                          is_prefix = true;
-                          raw_expected = true;
-                        }
-                      break;
-                    }
-
-                  if (is_prefix)
-                    goto string;
-                }
               phase4_ungetc (c);
               break;
             }
@@ -1509,148 +1430,69 @@ phase5_get (token_ty *tp)
          but ignoring it has no effect unless one of the keywords is
          "L".  Just pretend it won't happen.  Also, we don't need to
          remember the character constant.  */
-      last_was_backslash = false;
       for (;;)
         {
-          c = phase3_getc ();
-          if (last_was_backslash)
-            {
-              last_was_backslash = false;
-              continue;
-            }
-          switch (c)
+          c = phase7_getc ();
+          if (c == P7_NEWLINE)
             {
-            case '\\':
-              last_was_backslash = true;
-              /* FALLTHROUGH */
-            default:
-              continue;
-            case '\n':
               error_with_progname = false;
               error (0, 0, _("%s:%d: warning: unterminated character constant"),
                      logical_file_name, line_number - 1);
               error_with_progname = true;
-              phase3_ungetc ('\n');
-              break;
-            case EOF: case '\'':
+              phase7_ungetc ('\n');
               break;
             }
-          break;
+          if (c == EOF || c == P7_QUOTE)
+            break;
         }
       tp->type = token_type_character_constant;
       return;
 
     case '"':
       {
-      string:
+        struct mixed_string_buffer *bp;
+
+        /* Start accumulating the string.  */
+        bp = mixed_string_buffer_alloc (lc_string,
+                                        logical_file_name,
+                                        line_number);
+
         /* We could worry about the 'L' before wide string constants,
            but since gettext's argument is not a wide character string,
            let the compiler complain about the argument not matching the
            prototype.  Just pretend it won't happen.  */
-        last_was_backslash = false;
-        delimiter_left_end = -1;
-        delimiter_right_start = -1;
-        last_rparen = -1;
-        bufpos = 0;
         for (;;)
           {
-            c = phase3_getc ();
-            if (last_was_backslash && !raw_expected)
-              {
-                last_was_backslash = false;
-                if (bufpos >= bufmax)
-                  {
-                    bufmax = 2 * bufmax + 10;
-                    buffer = xrealloc (buffer, bufmax);
-                  }
-                buffer[bufpos++] = c;
-                continue;
-              }
-            switch (c)
-              {
-              case '\\':
-                last_was_backslash = true;
-                /* FALLTHROUGH */
-              default:
-                if (raw_expected)
-                  {
-                    if (c == '(' && delimiter_left_end < 0)
-                      delimiter_left_end = bufpos;
-                    else if (c == ')' && delimiter_left_end >= 0)
-                      last_rparen = bufpos;
-                  }
-                else if (c == '\n')
-                  {
-                    error_with_progname = false;
-                    error (0, 0,
-                           _("%s:%d: warning: unterminated string literal"),
-                           logical_file_name, line_number - 1);
-                    error_with_progname = true;
-                    phase3_ungetc ('\n');
-                    break;
-                  }
-                if (bufpos >= bufmax)
-                  {
-                    bufmax = 2 * bufmax + 10;
-                    buffer = xrealloc (buffer, bufmax);
-                  }
-                buffer[bufpos++] = c;
-                continue;
+            c = phase7_getc ();
 
-              case '"':
-                if (raw_expected && delimiter_left_end >= 0)
-                  {
-                    if (last_rparen < 0
-                        || delimiter_left_end != bufpos - (last_rparen + 1)
-                        || strncmp (buffer, buffer + last_rparen + 1,
-                                    delimiter_left_end) != 0)
-                      {
-                        if (bufpos >= bufmax)
-                          {
-                            bufmax = 2 * bufmax + 10;
-                            buffer = xrealloc (buffer, bufmax);
-                          }
-                        buffer[bufpos++] = c;
-                        continue;
-                      }
-                    delimiter_right_start = last_rparen;
-                  }
-                break;
+            /* Keep line_number in sync.  */
+            bp->line_number = line_number;
 
-              case EOF:
-                break;
-              }
-            break;
-          }
-        if (bufpos >= bufmax)
-          {
-            bufmax = 2 * bufmax + 10;
-            buffer = xrealloc (buffer, bufmax);
-          }
-        buffer[bufpos] = 0;
-
-        if (raw_expected)
-          {
-            if (delimiter_left_end < 0 || delimiter_right_start < 0)
+            if (c == P7_NEWLINE)
               {
                 error_with_progname = false;
                 error (0, 0, _("%s:%d: warning: unterminated string literal"),
                        logical_file_name, line_number - 1);
                 error_with_progname = true;
+                phase7_ungetc ('\n');
+                break;
               }
-            else
+            if (c == EOF || c == P7_QUOTES)
+              break;
+            if (c == P7_QUOTE)
+              c = '\'';
+            if (IS_UNICODE (c))
               {
-                buffer[delimiter_right_start] = '\0';
-                tp->type = token_type_string_literal;
-                tp->string = xstrdup (&buffer[delimiter_left_end + 1]);
-                tp->escape = LET_NONE;
-                tp->comment = add_reference (savable_comment);
-                return;
+                assert (UNICODE_VALUE (c) >= 0
+                        && UNICODE_VALUE (c) < 0x110000);
+                mixed_string_buffer_append_unicode (bp,
+                                                    UNICODE_VALUE (c));
               }
+            else
+              mixed_string_buffer_append_char (bp, c);
           }
         tp->type = token_type_string_literal;
-        tp->string = xstrdup (buffer);
-        tp->escape = LET_ANSI_C | LET_UNICODE;
+        tp->string = mixed_string_buffer_done (bp);
         tp->comment = add_reference (savable_comment);
         return;
       }
@@ -1904,7 +1746,6 @@ phase8a_get (token_ty *tp)
       tp->string = new_string;
       tp->comment = add_reference (savable_comment);
       tp->type = token_type_string_literal;
-      tp->escape = LET_ANSI_C | LET_UNICODE;
     }
 }
 
@@ -1985,10 +1826,7 @@ phase8c_unget (token_ty *tp)
 
 /* 8. Concatenate adjacent string literals to form single string
    literals (because we don't expand macros, there are a few things we
-   will miss).
-
-   FIXME: handle the case when the string literals have different
-   tp->escape setting.  */
+   will miss).  */
 
 static void
 phase8_get (token_ty *tp)
@@ -2044,9 +1882,6 @@ 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.  */
-  enum literalstring_escape_type escape;
-
   /* This field is used only for xgettext_token_type_string_literal.  */
   refcounted_string_list_ty *comment;
 
@@ -2122,7 +1957,6 @@ x_c_lex (xgettext_token_ty *tp)
 
           tp->type = xgettext_token_type_string_literal;
           tp->string = token.string;
-          tp->escape = token.escape;
           tp->comment = token.comment;
           tp->pos.file_name = logical_file_name;
           tp->pos.line_number = token.line_number;
@@ -2234,7 +2068,10 @@ extract_parenthesized (message_list_ty *mlp,
                                      arglist_parser_alloc (mlp,
                                                            state ? next_shapes : NULL)))
             {
+              xgettext_current_source_encoding = po_charset_utf8;
               arglist_parser_done (argparser, arg);
+              xgettext_current_source_encoding =
+                xgettext_global_source_encoding;
               return true;
             }
           next_context_iter = null_context_list_iterator;
@@ -2243,7 +2080,9 @@ extract_parenthesized (message_list_ty *mlp,
           continue;
 
         case xgettext_token_type_rparen:
+          xgettext_current_source_encoding = po_charset_utf8;
           arglist_parser_done (argparser, arg);
+          xgettext_current_source_encoding = xgettext_global_source_encoding;
           return false;
 
         case xgettext_token_type_comma:
@@ -2277,41 +2116,16 @@ extract_parenthesized (message_list_ty *mlp,
           continue;
 
         case xgettext_token_type_string_literal:
+          xgettext_current_source_encoding = po_charset_utf8;
           if (extract_all)
-            {
-              char *string;
-              refcounted_string_list_ty *comment;
-              const char *encoding;
-
-              string = literalstring_parse (token.string, &token.pos,
-                                            token.escape);
-              free (token.string);
-              token.string = string;
-
-              if (token.comment != NULL)
-                {
-                  comment = savable_comment_convert_encoding (token.comment,
-                                                              &token.pos);
-                  drop_reference (token.comment);
-                  token.comment = comment;
-                }
-
-              /* token.string and token.comment are already converted
-                 to UTF-8.  Prevent further conversion in
-                 remember_a_message.  */
-              encoding = xgettext_current_source_encoding;
-              xgettext_current_source_encoding = po_charset_utf8;
-              remember_a_message (mlp, NULL, token.string, inner_context,
-                                  &token.pos, NULL, token.comment);
-              xgettext_current_source_encoding = encoding;
-            }
+            remember_a_message (mlp, NULL, token.string, inner_context,
+                                &token.pos, NULL, token.comment);
           else
-            arglist_parser_remember_literal (argparser, arg, token.string,
-                                             inner_context,
-                                             token.pos.file_name,
-                                             token.pos.line_number,
-                                             token.comment,
-                                             token.escape);
+            arglist_parser_remember (argparser, arg, token.string,
+                                     inner_context,
+                                     token.pos.file_name, token.pos.line_number,
+                                     token.comment);
+          xgettext_current_source_encoding = xgettext_global_source_encoding;
           drop_reference (token.comment);
           next_context_iter = null_context_list_iterator;
           selectorcall_context_iter = null_context_list_iterator;
@@ -2325,7 +2139,9 @@ extract_parenthesized (message_list_ty *mlp,
           continue;
 
         case xgettext_token_type_eof:
+          xgettext_current_source_encoding = po_charset_utf8;
           arglist_parser_done (argparser, arg);
+          xgettext_current_source_encoding = xgettext_global_source_encoding;
           return true;
 
         default:
index 29b6f3674cdca6c86149fda352fdee7a11b5f00f..5413aea6c9c20958366b410275011e3b1c29ef51 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext C/C++/ObjectiveC backend.
-   Copyright (C) 2001-2003, 2006, 2009, 2015-2016 Free Software Foundation,
-   Inc.
+   Copyright (C) 2001-2003, 2006, 2009, 2014-2015, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -44,20 +43,16 @@ extern "C" {
 #define SCANNERS_C \
   { "C",                extract_c,                                      \
                         &flag_table_c,                                  \
-                        &formatstring_c, NULL,                          \
-                        &literalstring_c },                             \
+                        &formatstring_c, NULL },                        \
   { "C++",              extract_cxx,                                    \
                         &flag_table_c,                                  \
-                        &formatstring_c, NULL,                          \
-                        &literalstring_c },                             \
+                        &formatstring_c, NULL },                        \
   { "ObjectiveC",       extract_objc,                                   \
                         &flag_table_objc,                               \
-                        &formatstring_c, &formatstring_objc,            \
-                        &literalstring_c },                             \
+                        &formatstring_c, &formatstring_objc },          \
   { "GCC-source",       extract_c,                                      \
                         &flag_table_gcc_internal,                       \
-                        &formatstring_gcc_internal, &formatstring_gfc_internal, \
-                        &literalstring_c },                             \
+                        &formatstring_gcc_internal, &formatstring_gfc_internal }, \
 
 /* Scan a C file and add its translatable strings to mdlp.  */
 extern void extract_c (FILE *fp, const char *real_filename,
@@ -93,9 +88,6 @@ extern void init_flag_table_gcc_internal (void);
 extern void init_flag_table_kde (void);
 
 
-extern struct literalstring_parser literalstring_c;
-
-
 #ifdef __cplusplus
 }
 #endif
index 1fcece4bad6f18a31f7398985a8c12cfb48ae0f4..27f0b024156e18723736a54e451c6fe6ded86da5 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext C# backend.
-   Copyright (C) 2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_CSHARP \
   { "C#",               extract_csharp,                                   \
-                        &flag_table_csharp, &formatstring_csharp, NULL, NULL }, \
+                        &flag_table_csharp, &formatstring_csharp, NULL }, \
 
 extern void extract_csharp (FILE *fp, const char *real_filename,
                             const char *logical_filename,
index f73d5b63c1f18eed2a02d35c0f281720a83c0bf0..47242e3a93cecc6efece795ba145b0a1a121421e 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Desktop Entry backend.
-   Copyright (C) 2014-2016 Free Software Foundation, Inc.
+   Copyright (C) 2014, 2018 Free Software Foundation, Inc.
    Written by Daiki Ueno <ueno@gnu.org>, 2014.
 
    This program is free software: you can redistribute it and/or modify
@@ -31,7 +31,7 @@ extern "C" {
   { "desktop", "Desktop" }, \
 
 #define SCANNERS_DESKTOP \
-  { "Desktop", extract_desktop, NULL, NULL, NULL, NULL }, \
+  { "Desktop", extract_desktop, NULL, NULL, NULL }, \
 
 /* Scan a Desktop Entry file and add its translatable strings to mdlp.  */
 extern void extract_desktop (FILE *fp, const char *real_filename,
index 009b71db856a01865b308706e55404bcd6a90603..99490c258e412b38110e8ad26175acb5085b3c8a 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Emacs Lisp backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_ELISP \
   { "EmacsLisp",        extract_elisp,                                  \
-                        &flag_table_elisp, &formatstring_elisp, NULL, NULL }, \
+                        &flag_table_elisp, &formatstring_elisp, NULL }, \
 
 /* Scan an Emacs Lisp file and add its translatable strings to mdlp.  */
 extern void extract_elisp (FILE *fp, const char *real_filename,
index 19d33ceea9cb464423688f46a170f3d20cc9224f..1c70bba37297614196d4b1d7cd542eb6cef366c4 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext glade backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2013-2015, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -36,7 +36,7 @@ extern "C" {
   { "ui",        NULL    },                                          \
 
 #define SCANNERS_GLADE \
-  { "glade",            NULL, NULL, NULL, NULL, NULL },              \
+  { "glade",            NULL, NULL, NULL, NULL },                    \
 
 
 #ifdef __cplusplus
index e7f53fc9c3a9d0bacf57e01bc29c8d63a1f4421b..2f1da540f87ec5a08c09464edac6fd8f7e9d91c2 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext GSettings schema file backend.
-   Copyright (C) 2002-2003, 2006, 2013, 2015-2016 Free Software Foundation,
-   Inc.
+   Copyright (C) 2002-2003, 2006, 2013-2015, 2018 Free Software Foundation, Inc.
    Written by Daiki Ueno <ueno@gnu.org>, 2013.
 
    This program is free software: you can redistribute it and/or modify
@@ -34,7 +33,7 @@ extern "C" {
   { "gschema.xml", NULL }, \
 
 #define SCANNERS_GSETTINGS \
-  { "gsettings", NULL, NULL, NULL, NULL, NULL }, \
+  { "gsettings", NULL, NULL, NULL, NULL },      \
 
 
 #ifdef __cplusplus
index 3863f1621b8fa1831f591dca96206118bddfdf09..b2487e2dc9571a0a69d7de9a20a8404ca4be4b69 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Java backend.
-   Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Tommy Johansson <tommy.johansson@kanalen.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_JAVA \
   { "Java",             extract_java,                                   \
-                        &flag_table_java, &formatstring_java, NULL, NULL },   \
+                        &flag_table_java, &formatstring_java, NULL },   \
 
 extern void extract_java (FILE *fp, const char *real_filename,
                           const char *logical_filename,
index 87dc427847352891516b5223df766e30b54fc366..c59acc306676dfa110b8797fc490239f4d5cdcdc 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext JavaScript backend.
-   Copyright (C) 2002-2003, 2006, 2013, 2015-2016 Free Software Foundation,
-   Inc.
+   Copyright (C) 2002-2003, 2006, 2010, 2013-2014, 2018 Free Software Foundation, Inc.
    This file was written by Andreas Stricker <andy@knitter.ch>, 2010.
    It's based on x-python from Bruno Haible.
 
@@ -34,7 +33,7 @@ extern "C" {
 
 #define SCANNERS_JAVASCRIPT \
   { "JavaScript",       extract_javascript,                               \
-                        &flag_table_javascript, &formatstring_javascript, NULL, NULL }, \
+                        &flag_table_javascript, &formatstring_javascript, NULL }, \
 
 /* Scan a Python file and add its translatable strings to mdlp.  */
 extern void extract_javascript (FILE *fp, const char *real_filename,
index 6e57f38be0017a2ea63958179063562afca10449..e1b735b6ede28947e893f4ee73b99367965f3aea 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext librep backend.
-   Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_LIBREP \
   { "librep",           extract_librep,                                   \
-                        &flag_table_librep, &formatstring_librep, NULL, NULL }, \
+                        &flag_table_librep, &formatstring_librep, NULL }, \
 
 /* Scan a librep file and add its translatable strings to mdlp.  */
 extern void extract_librep (FILE *fp, const char *real_filename,
index 9a762c680419658a61346db138da96be7117c5e7..ea7512395acdc3cae4fb1572a49aba61b66558b3 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Lisp backend.
-   Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_LISP \
   { "Lisp",             extract_lisp,                                   \
-                        &flag_table_lisp, &formatstring_lisp, NULL, NULL },   \
+                        &flag_table_lisp, &formatstring_lisp, NULL },   \
 
 /* Scan a Lisp file and add its translatable strings to mdlp.  */
 extern void extract_lisp (FILE *fp, const char *real_filename,
index f4b615ed086ef440c3badd93d8c92f0e63b6dc6e..e30c751e20c5e2e61e90bb6c503344e3a326cd0c 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Lua backend.
-   Copyright (C) 2011, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2011-2014, 2018 Free Software Foundation, Inc.
    Written by Ä½ubomír Remák <lubomirrk@lubomirr.eu>, 2011
 
    This program is free software: you can redistribute it and/or modify
@@ -30,7 +30,7 @@ extern "C"
 
 #define SCANNERS_LUA \
   { "Lua",             extract_lua,                                     \
-                       &flag_table_lua, &formatstring_lua, NULL, NULL },      \
+                       &flag_table_lua, &formatstring_lua, NULL },      \
 
   /* Scan a Lua file and add its translatable strings to mdlp.  */
   extern void extract_lua (FILE * fp, const char *real_filename,
index a5845503c9e8b6dc68ebb0b80ff3acb76b2bf21c..4832c9ba4a7afc0ab4eaa48917c781ebb4f7207a 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext Perl backend.
-   Copyright (C) 2002-2003, 2006, 2010, 2015-2016 Free Software Foundation,
-   Inc.
+   Copyright (C) 2002-2003, 2006, 2010, 2014, 2018 Free Software Foundation, Inc.
    Written by Guido Flohr <guido@imperia.net>, 2002-2003
 
    This program is free software: you can redistribute it and/or modify
@@ -37,7 +36,7 @@ extern "C" {
 
 #define SCANNERS_PERL \
   { "perl",             extract_perl,                                   \
-            &flag_table_perl, &formatstring_perl, &formatstring_perl_brace, NULL }, \
+            &flag_table_perl, &formatstring_perl, &formatstring_perl_brace }, \
 
 /* Scan a Perl file and add its translatable strings to mdlp.  */
 extern void extract_perl (FILE *fp, const char *real_filename,
index 12e016b1ecaa9b33ca7f8e1429e4a84d610097f0..2a0c216f918c9de9961928857f20b6f6ba3c560d 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext PHP backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -34,7 +34,7 @@ extern "C" {
 
 #define SCANNERS_PHP \
   { "PHP",              extract_php,                                    \
-                        &flag_table_php, &formatstring_php, NULL, NULL },     \
+                        &flag_table_php, &formatstring_php, NULL },     \
 
 /* Scan a PHP file and add its translatable strings to mdlp.  */
 extern void extract_php (FILE *fp, const char *real_filename,
index 332b9bbbfe54c0e3701b911015b22f2c13a0866c..c2f8ead400cbbedf287b3bfb75e8118fe035fee1 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext PO backend.
-   Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
   { "pot",    "PO"    },                                                \
 
 #define SCANNERS_PO \
-  { "PO",               extract_po, NULL, NULL, NULL, NULL },                 \
+  { "PO",               extract_po, NULL, NULL, NULL },                 \
 
 /* Scan a PO file and add its translatable strings to mdlp.  */
 extern void extract_po (FILE *fp, const char *real_filename,
index 21092d6d0ce278e5674bdf96932019470a999cb4..09a422ce0bc1b97e22274dedfea89000abdab04d 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext JavaProperties backend.
-   Copyright (C) 2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -31,7 +31,7 @@ extern "C" {
   { "properties", "JavaProperties" },                                   \
 
 #define SCANNERS_PROPERTIES \
-  { "JavaProperties",   extract_properties, NULL, NULL, NULL, NULL },         \
+  { "JavaProperties",   extract_properties, NULL, NULL, NULL },         \
 
 /* Scan a JavaProperties file and add its translatable strings to mdlp.  */
 extern void extract_properties (FILE *fp, const char *real_filename,
index 72822a3394fd7d3879ccd0b9a53c11e719e5909f..8b0ff366c66499675c0f614b8a3abf2322acd5b6 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Python backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2013-2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_PYTHON \
   { "Python",           extract_python,                                   \
-                        &flag_table_python, &formatstring_python, &formatstring_python_brace, NULL }, \
+                        &flag_table_python, &formatstring_python, &formatstring_python_brace }, \
 
 /* Scan a Python file and add its translatable strings to mdlp.  */
 extern void extract_python (FILE *fp, const char *real_filename,
index ee7c191d64a998581a4141c02c4fe6269c9db0e0..c470d0e4e51262ea73c257a1657bedfa8ee682f0 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext RST/RSJ backend.
-   Copyright (C) 2001-2003, 2006, 2015-2016, 2018 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -33,9 +33,9 @@ extern "C" {
 
 #define SCANNERS_RST \
   { "RST",              extract_rst,                                    \
-                        NULL, &formatstring_pascal, NULL, NULL },       \
+                        NULL, &formatstring_pascal, NULL },             \
   { "RSJ",              extract_rsj,                                    \
-                        NULL, &formatstring_pascal, NULL, NULL },       \
+                        NULL, &formatstring_pascal, NULL },             \
 
 /* Scan an RST file and add its translatable strings to mdlp.  */
 extern void extract_rst (FILE *fp, const char *real_filename,
index 8d045065dc044664fa9636c34497a1b3a884b058..b6ef0669a8680a8fc7f60347c78d0742d40044f2 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Scheme backend.
-   Copyright (C) 2004, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2004.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_SCHEME \
   { "Scheme",           extract_scheme,                                   \
-                        &flag_table_scheme, &formatstring_scheme, NULL, NULL }, \
+                        &flag_table_scheme, &formatstring_scheme, NULL }, \
 
 /* Scan a Scheme file and add its translatable strings to mdlp.  */
 extern void extract_scheme (FILE *fp, const char *real_filename,
index 2c4ab9ef805fa78b1678fd655a86cb53f83b5381..4bda07d2f69293ad12401356ac2a85c13fce0663 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext sh backend.
-   Copyright (C) 2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -33,7 +33,7 @@ extern "C" {
 
 #define SCANNERS_SH \
   { "Shell",            extract_sh,                                     \
-                        &flag_table_sh, &formatstring_sh, NULL, NULL },       \
+                        &flag_table_sh, &formatstring_sh, NULL },       \
 
 /* Scan a shell script file and add its translatable strings to mdlp.  */
 extern void extract_sh (FILE *fp, const char *real_filename,
index b8e2d0bdfb18f59a5a5aa9b4ead9ab251ab55954..f851b56073d053e051c3aba5d5a5aeb7a08644ee 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Smalltalk backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_SMALLTALK \
   { "Smalltalk",        extract_smalltalk,                              \
-                        NULL, &formatstring_smalltalk, NULL, NULL },          \
+                        NULL, &formatstring_smalltalk, NULL },          \
 
 /* Scan a Smalltalk file and add its translatable strings to mdlp.  */
 extern void extract_smalltalk (FILE *fp, const char *real_filename,
index 2df0c87c1c68e817a34a9e5c045da0fc172a19f4..e9ec1755f320a57deb376fe436a6d94df6b45c78 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext NXStringTable backend.
-   Copyright (C) 2003, 2006, 2015-2016, 2018 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -31,7 +31,7 @@ extern "C" {
   { "strings", "NXStringTable" },                                       \
 
 #define SCANNERS_STRINGTABLE \
-  { "NXStringTable",    extract_stringtable, NULL, NULL, NULL, NULL },        \
+  { "NXStringTable",    extract_stringtable, NULL, NULL, NULL },        \
 
 /* Scan an NXStringTable file and add its translatable strings to mdlp.  */
 extern void extract_stringtable (FILE *fp, const char *real_filename,
index 5b4be7f5099ca2555f57001c6b130dc64aaae7d7..e802950eba65bd08e7a30de12903d2d0d8ae773d 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Tcl Lisp backend.
-   Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2002.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_TCL \
   { "Tcl",              extract_tcl,                                    \
-                        &flag_table_tcl, &formatstring_tcl, NULL, NULL },     \
+                        &flag_table_tcl, &formatstring_tcl, NULL },     \
 
 /* Scan a Tcl file and add its translatable strings to mdlp.  */
 extern void extract_tcl (FILE *fp, const char *real_filename,
index cda642e0558c882e0ccb2cca2a4bf31a77ac86c1..073448f71e41673cf82a790d6b8a06bc95a76488 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Vala backend.
-   Copyright (C) 2013, 2015-2018 Free Software Foundation, Inc.
+   Copyright (C) 2013-2014, 2018 Free Software Foundation, Inc.
 
    This file was written by Daiki Ueno <ueno@gnu.org>, 2013.
 
@@ -366,7 +366,6 @@ struct token_ty
   token_type_ty type;
   char *string;         /* for token_type_symbol, token_type_string_literal */
   refcounted_string_list_ty *comment;   /* for token_type_string_literal */
-  enum literalstring_escape_type escape;
   int line_number;
 };
 
@@ -381,6 +380,211 @@ free_token (token_ty *tp)
 }
 
 
+/* Return value of phase7_getc when EOF is reached.  */
+#define P7_EOF (-1)
+#define P7_STRING_END (-2)
+
+/* Replace escape sequences within character strings with their single
+   character equivalents.  */
+#define P7_QUOTES (-3)
+#define P7_QUOTE (-4)
+#define P7_NEWLINE (-5)
+
+/* Convert an UTF-16 or UTF-32 code point to a return value that can be
+   distinguished from a single-byte return value.  */
+#define UNICODE(code) (0x100 + (code))
+
+/* Test a return value of phase7_getuc whether it designates an UTF-16 or
+   UTF-32 code point.  */
+#define IS_UNICODE(p7_result) ((p7_result) >= 0x100)
+
+/* Extract the UTF-16 or UTF-32 code of a return value that satisfies
+   IS_UNICODE.  */
+#define UNICODE_VALUE(p7_result) ((p7_result) - 0x100)
+
+
+static int
+phase7_getc ()
+{
+  int c, n, j;
+
+  /* Use phase 1, because phase 2 elides comments.  */
+  c = phase1_getc ();
+
+  /* Return a magic newline indicator, so that we can distinguish
+     between the user requesting a newline in the string (e.g. using
+     "\n" or "\012") from the user failing to terminate the string or
+     character constant.  The ANSI C standard says: 3.1.3.4 Character
+     Constants contain "any character except single quote, backslash or
+     newline; or an escape sequence" and 3.1.4 String Literals contain
+     "any character except double quote, backslash or newline; or an
+     escape sequence".
+
+     Most compilers give a fatal error in this case, however gcc is
+     stupidly silent, even though this is a very common typo.  OK, so
+     "gcc --pedantic" will tell me, but that gripes about too much other
+     stuff.  Could I have a "gcc -Wnewline-in-string" option, or
+     better yet a "gcc -fno-newline-in-string" option, please?  Gcc is
+     also inconsistent between string literals and character constants:
+     you may not embed newlines in character constants; try it, you get
+     a useful diagnostic.  --PMiller  */
+  if (c == '\n')
+    return P7_NEWLINE;
+
+  if (c == '"')
+    return P7_QUOTES;
+  if (c == '\'')
+    return P7_QUOTE;
+  if (c != '\\')
+    return c;
+  c = phase1_getc ();
+  switch (c)
+    {
+    default:
+      /* Unknown escape sequences really should be an error, but just
+         ignore them, and let the real compiler complain.  */
+      phase1_ungetc (c);
+      return '\\';
+
+    case '"':
+    case '\'':
+    case '?':
+    case '\\':
+      return c;
+
+    case 'a':
+      return '\a';
+    case 'b':
+      return '\b';
+
+      /* The \e escape is preculiar to gcc, and assumes an ASCII
+         character set (or superset).  We don't provide support for it
+         here.  */
+
+    case 'f':
+      return '\f';
+    case 'n':
+      return '\n';
+    case 'r':
+      return '\r';
+    case 't':
+      return '\t';
+    case 'v':
+      return '\v';
+
+    case 'x':
+      c = phase1_getc ();
+      switch (c)
+        {
+        default:
+          phase1_ungetc (c);
+          phase1_ungetc ('x');
+          return '\\';
+
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+          break;
+        }
+      n = 0;
+      for (;;)
+        {
+          switch (c)
+            {
+            default:
+              phase1_ungetc (c);
+              return n;
+
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+              n = n * 16 + c - '0';
+              break;
+
+            case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+              n = n * 16 + 10 + c - 'A';
+              break;
+
+            case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+              n = n * 16 + 10 + c - 'a';
+              break;
+            }
+          c = phase1_getc ();
+        }
+      return n;
+
+    case '0': case '1': case '2': case '3':
+    case '4': case '5': case '6': case '7':
+      n = 0;
+      for (j = 0; j < 3; ++j)
+        {
+          n = n * 8 + c - '0';
+          c = phase1_getc ();
+          switch (c)
+            {
+            default:
+              break;
+
+            case '0': case '1': case '2': case '3':
+            case '4': case '5': case '6': case '7':
+              continue;
+            }
+          break;
+        }
+      phase1_ungetc (c);
+      return n;
+
+    case 'U': case 'u':
+      {
+        unsigned char buf[8];
+
+        n = 0;
+        for (j = 0; j < (c == 'u' ? 4 : 8); j++)
+          {
+            int c1 = phase1_getc ();
+
+            if (c1 >= '0' && c1 <= '9')
+              n = (n << 4) + (c1 - '0');
+            else if (c1 >= 'A' && c1 <= 'F')
+              n = (n << 4) + (c1 - 'A' + 10);
+            else if (c1 >= 'a' && c1 <= 'f')
+              n = (n << 4) + (c1 - 'a' + 10);
+            else
+              {
+                phase1_ungetc (c1);
+                while (--j >= 0)
+                  phase1_ungetc (buf[j]);
+                phase1_ungetc (c);
+                return '\\';
+              }
+
+            buf[j] = c1;
+          }
+
+        if (n < 0x110000)
+          return UNICODE (n);
+
+        error_with_progname = false;
+        error (0, 0, _("%s:%d: warning: invalid Unicode character"),
+               logical_file_name, line_number);
+        error_with_progname = true;
+
+        while (--j >= 0)
+          phase1_ungetc (buf[j]);
+        phase1_ungetc (c);
+        return '\\';
+      }
+    }
+}
+
+
+static void
+phase7_ungetc (int c)
+{
+  phase1_ungetc (c);
+}
+
+
 /* 3. Parse each resulting logical line as preprocessing tokens and
    white space.  Preprocessing tokens and Vala tokens don't always
    match.  */
@@ -429,7 +633,6 @@ phase3_get (token_ty *tp)
   static char *buffer;
   static int bufmax;
   int bufpos;
-  int last_was_backslash;
 
 #undef APPEND
 #define APPEND(c)                               \
@@ -598,33 +801,20 @@ phase3_get (token_ty *tp)
           return;
 
         case '\'':
-          last_was_backslash = false;
           for (;;)
             {
-              c = phase2_getc ();
-              if (last_was_backslash)
+              c = phase7_getc ();
+              if (c == P7_NEWLINE)
                 {
-                  last_was_backslash = false;
-                  continue;
-                }
-              switch (c)
-                {
-                case '\\':
-                  last_was_backslash = true;
-                  /* FALLTHROUGH */
-                default:
-                  continue;
-                case '\n':
                   error_with_progname = false;
                   error (0, 0, _("%s:%d: warning: unterminated character constant"),
                          logical_file_name, line_number - 1);
                   error_with_progname = true;
-                  phase2_ungetc ('\n');
-                  break;
-                case EOF: case '\'':
+                  phase7_ungetc ('\n');
                   break;
                 }
-              break;
+              if (c == EOF || c == P7_QUOTE)
+                break;
             }
           tp->type = last_token_type = token_type_character_constant;
           return;
@@ -637,7 +827,7 @@ phase3_get (token_ty *tp)
                """...""" (where ... can include newlines and double quotes)
              String templates.
                @"...", @"""..."""
-          
+
              Note that, with the current implementation string
              templates are not subject to translation, because they are
              inspected at compile time.  For example, the following code
@@ -660,90 +850,90 @@ phase3_get (token_ty *tp)
           /* FALLTHROUGH */
         case '"':
           {
-            int c2 = phase2_getc ();
+            struct mixed_string_buffer *bp;
+            int c2 = phase1_getc ();
 
             if (c2 == '"')
               {
-                int c3 = phase2_getc ();
+                int c3 = phase1_getc ();
                 if (c3 == '"')
                   verbatim = true;
                 else
                   {
-                    phase2_ungetc (c3);
-                    phase2_ungetc (c2);
+                    phase1_ungetc (c3);
+                    phase1_ungetc (c2);
                   }
               }
             else
               phase2_ungetc (c2);
 
+            /* Start accumulating the string.  */
+            bp = mixed_string_buffer_alloc (lc_string,
+                                            logical_file_name,
+                                            line_number);
             if (verbatim)
-              {
-                bufpos = 0;
-                for (;;)
-                  {
-                    /* Use phase 1, because phase 2 elides comments.  */
-                    c = phase1_getc ();
-                    if (c == EOF)
-                      break;
+              for (;;)
+                {
+                  c = phase1_getc ();
 
-                    if (c == '"')
-                      {
-                        int c2 = phase1_getc ();
-                        if (c2 == '"')
-                          {
-                            int c3 = phase1_getc ();
-                            if (c3 == '"')
-                              break;
-                            phase1_ungetc (c3);
-                          }
-                        phase1_ungetc (c2);
-                      }
-                    APPEND (c);
-                  }
-              }
+                  /* Keep line_number in sync.  */
+                  bp->line_number = line_number;
+
+                  if (c == '"')
+                    {
+                      int c2 = phase1_getc ();
+                      if (c2 == '"')
+                        {
+                          int c3 = phase1_getc ();
+                          if (c3 == '"')
+                            break;
+                          phase1_ungetc (c3);
+                        }
+                      phase1_ungetc (c2);
+                    }
+                  if (c == EOF)
+                    break;
+                  mixed_string_buffer_append_char (bp, c);
+                }
             else
-              {
-                last_was_backslash = false;
-                bufpos = 0;
-                for (;;)
-                  {
-                    c = phase1_getc ();
-                    if (last_was_backslash)
-                      {
-                        last_was_backslash = false;
-                        APPEND (c);
-                        continue;
-                      }
-
-                    switch (c)
-                      {
-                      case '\\':
-                        last_was_backslash = true;
-                        /* FALLTHROUGH */
-                      default:
-                        APPEND (c);
-                        continue;
-
-                      case '\n':
-                        error_with_progname = false;
-                        error (0, 0, _("\
+              for (;;)
+                {
+                  c = phase7_getc ();
+
+                  /* Keep line_number in sync.  */
+                  bp->line_number = line_number;
+
+                  if (c == P7_NEWLINE)
+                    {
+                      error_with_progname = false;
+                      error (0, 0, _("\
 %s:%d: warning: unterminated string literal"),
-                               logical_file_name, line_number - 1);
-                        error_with_progname = true;
-                        phase1_ungetc ('\n');
-                        break;
-                      case EOF: case '"':
-                        break;
-                      }
+                             logical_file_name, line_number - 1);
+                      error_with_progname = true;
+                      phase7_ungetc ('\n');
+                      break;
+                    }
+                  if (c == P7_QUOTES)
                     break;
-                  }
-              }
-            APPEND (0);
-            tp->type = last_token_type = template
-              ? token_type_string_template : token_type_string_literal;
-            tp->string = xstrdup (buffer);
+                  if (c == EOF)
+                    break;
+                  if (c == P7_QUOTE)
+                    c = '\'';
+                  if (IS_UNICODE (c))
+                    {
+                      assert (UNICODE_VALUE (c) >= 0
+                              && UNICODE_VALUE (c) < 0x110000);
+                      mixed_string_buffer_append_unicode (bp,
+                                                          UNICODE_VALUE (c));
+                    }
+                  else
+                    mixed_string_buffer_append_char (bp, c);
+                }
+            /* Done accumulating the string.  */
+            tp->type = last_token_type =
+              template ? token_type_string_template : token_type_string_literal;
+            tp->string = mixed_string_buffer_done (bp);
             tp->comment = add_reference (savable_comment);
-            tp->escape = verbatim ? 0 : LET_ANSI_C | LET_UNICODE;
             return;
           }
 
@@ -878,7 +1068,7 @@ phase3_get (token_ty *tp)
               }
             return;
           }
-          
+
         case '>':
         case '<':
           {
@@ -904,7 +1094,7 @@ phase3_get (token_ty *tp)
               }
             return;
           }
-          
+
         case ',':
           tp->type = last_token_type = token_type_comma;
           return;
@@ -1012,8 +1202,6 @@ x_vala_lex (token_ty *tp)
 /* Context lookup table.  */
 static flag_context_list_table_ty *flag_context_list_table;
 
-/* Use the same literalstring_parser provided by the C scanner.  */
-extern struct literalstring_parser literalstring_c;
 
 /* The file is broken into tokens.  Scan the token stream, looking for
    a keyword, followed by a left paren, followed by a string.  When we
@@ -1094,7 +1282,9 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim,
                                 arglist_parser_alloc (mlp,
                                                       state ? next_shapes : NULL)))
             {
+              xgettext_current_source_encoding = po_charset_utf8;
               arglist_parser_done (argparser, arg);
+              xgettext_current_source_encoding = xgettext_global_source_encoding;
               return true;
             }
           next_context_iter = null_context_list_iterator;
@@ -1104,7 +1294,9 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim,
         case token_type_rparen:
           if (delim == token_type_rparen || delim == token_type_eof)
             {
+              xgettext_current_source_encoding = po_charset_utf8;
               arglist_parser_done (argparser, arg);
+              xgettext_current_source_encoding = xgettext_global_source_encoding;
               return false;
             }
 
@@ -1123,7 +1315,9 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim,
           continue;
 
         case token_type_eof:
+          xgettext_current_source_encoding = po_charset_utf8;
           arglist_parser_done (argparser, arg);
+          xgettext_current_source_encoding = xgettext_global_source_encoding;
           return true;
 
         case token_type_string_literal:
@@ -1132,59 +1326,29 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim,
             pos.file_name = logical_file_name;
             pos.line_number = token.line_number;
 
+            xgettext_current_source_encoding = po_charset_utf8;
             if (extract_all)
-              {
-                char *string;
-                refcounted_string_list_ty *comment;
-                const char *encoding;
-
-                string = literalstring_c.parse (token.string, &pos,
-                                                token.escape);
-                free (token.string);
-                token.string = string;
-
-                if (token.comment != NULL)
-                  {
-                    comment = savable_comment_convert_encoding (token.comment,
-                                                                &pos);
-                    drop_reference (token.comment);
-                    token.comment = comment;
-                  }
-
-                /* token.string and token.comment are already converted
-                   to UTF-8.  Prevent further conversion in
-                   remember_a_message.  */
-                encoding = xgettext_current_source_encoding;
-                xgettext_current_source_encoding = po_charset_utf8;
-                remember_a_message (mlp, NULL, token.string, inner_context,
-                                    &pos, NULL, token.comment);
-                xgettext_current_source_encoding = encoding;
-              }
+              remember_a_message (mlp, NULL, token.string, inner_context,
+                                  &pos, NULL, token.comment);
             else
               {
-                /* A string immediately after a symbol means a
-                   function call.  */
+                /* A string immediately after a symbol means a function call.  */
                 if (state)
                   {
                     struct arglist_parser *tmp_argparser;
                     tmp_argparser = arglist_parser_alloc (mlp, next_shapes);
 
-                    arglist_parser_remember_literal (tmp_argparser, 1,
-                                                     token.string,
-                                                     inner_context,
-                                                     pos.file_name,
-                                                     pos.line_number,
-                                                     token.comment,
-                                                     token.escape);
+                    arglist_parser_remember (tmp_argparser, 1, token.string,
+                                             inner_context, pos.file_name,
+                                             pos.line_number, token.comment);
                     arglist_parser_done (tmp_argparser, 1);
                   }
                 else
-                  arglist_parser_remember_literal (argparser, arg, token.string,
-                                                   inner_context, pos.file_name,
-                                                   pos.line_number,
-                                                   token.comment,
-                                                   token.escape);
+                  arglist_parser_remember (argparser, arg, token.string,
+                                           inner_context, pos.file_name,
+                                           pos.line_number, token.comment);
               }
+            xgettext_current_source_encoding = xgettext_global_source_encoding;
           }
           drop_reference (token.comment);
           next_context_iter = null_context_list_iterator;
index 4554d76e6c28c7abd05a93ab786636c3598cbb63..47ef5b5d8c45ea0235c7b0bebabb260d88883cb8 100644 (file)
@@ -1,6 +1,5 @@
 /* xgettext Vala backend.
-   Copyright (C) 2002-2003, 2006, 2013, 2015-2016 Free Software Foundation,
-   Inc.
+   Copyright (C) 2002-2003, 2006, 2013-2014, 2018 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -31,8 +30,8 @@ extern "C" {
   { "vala",        "Vala"   },                                        \
 
 #define SCANNERS_VALA \
-  { "Vala",       extract_vala,                               \
-                  &flag_table_vala, &formatstring_c, NULL, &literalstring_c }, \
+  { "Vala",       extract_vala,                                       \
+                  &flag_table_vala, &formatstring_c, NULL },          \
 
 /* Scan a Vala file and add its translatable strings to mdlp.  */
 extern void extract_vala (FILE *fp, const char *real_filename,
index 22b5cf368f14792ea2dadf95c67d9a8980c499d0..b6d139a2282fc6f7e43d7e7a2bfeffdc5df31520 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext YCP backend.
-   Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -32,7 +32,7 @@ extern "C" {
 
 #define SCANNERS_YCP \
   { "YCP",              extract_ycp,                                    \
-                        &flag_table_ycp, &formatstring_ycp, NULL, NULL },     \
+                        &flag_table_ycp, &formatstring_ycp, NULL },     \
 
 /* Scan an YCP file and add its translatable strings to mdlp.  */
 extern void extract_ycp (FILE *fp, const char *real_filename,
index 00d5a946bc569ac4911fc37cd89b5a5eb5f6365d..adec0dff7413f911e1e398582c6dcedcb2a9d64b 100644 (file)
@@ -295,7 +295,6 @@ struct extractor_ty
   struct formatstring_parser *formatstring_parser1;
   struct formatstring_parser *formatstring_parser2;
   struct formatstring_parser *formatstring_parser3;
-  struct literalstring_parser *literalstring_parser;
 };
 
 
@@ -2127,32 +2126,6 @@ savable_comment_to_xgettext_comment (refcounted_string_list_ty *rslp)
     }
 }
 
-refcounted_string_list_ty *
-savable_comment_convert_encoding (refcounted_string_list_ty *comment,
-                                  lex_pos_ty *pos)
-{
-  refcounted_string_list_ty *result;
-  size_t i;
-
-  result = XMALLOC (refcounted_string_list_ty);
-  result->refcount = 1;
-  string_list_init (&result->contents);
-
-  for (i = 0; i < comment->contents.nitems; i++)
-    {
-      const char *old_string = comment->contents.item[i];
-      char *string = from_current_source_encoding (old_string,
-                                                   lc_comment,
-                                                   pos->file_name,
-                                                   pos->line_number);
-      string_list_append (&result->contents, string);
-      if (string != old_string)
-        free (string);
-    }
-
-  return result;
-}
-
 
 
 static FILE *
@@ -2222,7 +2195,6 @@ static struct formatstring_parser *current_formatstring_parser1;
 static struct formatstring_parser *current_formatstring_parser2;
 static struct formatstring_parser *current_formatstring_parser3;
 
-static struct literalstring_parser *current_literalstring_parser;
 
 static void
 extract_from_file (const char *file_name, extractor_ty extractor,
@@ -2242,7 +2214,6 @@ extract_from_file (const char *file_name, extractor_ty extractor,
   current_formatstring_parser1 = extractor.formatstring_parser1;
   current_formatstring_parser2 = extractor.formatstring_parser2;
   current_formatstring_parser3 = extractor.formatstring_parser3;
-  current_literalstring_parser = extractor.literalstring_parser;
   extractor.func (fp, real_file_name, logical_file_name, extractor.flag_table,
                   mdlp);
 
@@ -2992,17 +2963,14 @@ arglist_parser_alloc (message_list_ty *mlp, const struct callshapes *shapes)
           ap->alternative[i].argtotal = shapes->shapes[i].argtotal;
           ap->alternative[i].xcomments = shapes->shapes[i].xcomments;
           ap->alternative[i].msgctxt = NULL;
-          ap->alternative[i].msgctxt_escape = LET_NONE;
           ap->alternative[i].msgctxt_pos.file_name = NULL;
           ap->alternative[i].msgctxt_pos.line_number = (size_t)(-1);
           ap->alternative[i].msgid = NULL;
-          ap->alternative[i].msgid_escape = LET_NONE;
           ap->alternative[i].msgid_context = null_context;
           ap->alternative[i].msgid_pos.file_name = NULL;
           ap->alternative[i].msgid_pos.line_number = (size_t)(-1);
           ap->alternative[i].msgid_comment = NULL;
           ap->alternative[i].msgid_plural = NULL;
-          ap->alternative[i].msgid_plural_escape = LET_NONE;
           ap->alternative[i].msgid_plural_context = null_context;
           ap->alternative[i].msgid_plural_pos.file_name = NULL;
           ap->alternative[i].msgid_plural_pos.line_number = (size_t)(-1);
@@ -3040,16 +3008,13 @@ arglist_parser_clone (struct arglist_parser *ap)
       ccp->argtotal = cp->argtotal;
       ccp->xcomments = cp->xcomments;
       ccp->msgctxt = (cp->msgctxt != NULL ? xstrdup (cp->msgctxt) : NULL);
-      ccp->msgctxt_escape = cp->msgctxt_escape;
       ccp->msgctxt_pos = cp->msgctxt_pos;
       ccp->msgid = (cp->msgid != NULL ? xstrdup (cp->msgid) : NULL);
-      ccp->msgid_escape = cp->msgid_escape;
       ccp->msgid_context = cp->msgid_context;
       ccp->msgid_pos = cp->msgctxt_pos;
       ccp->msgid_comment = add_reference (cp->msgid_comment);
       ccp->msgid_plural =
         (cp->msgid_plural != NULL ? xstrdup (cp->msgid_plural) : NULL);
-      ccp->msgid_plural_escape = cp->msgid_plural_escape;
       ccp->msgid_plural_context = cp->msgid_plural_context;
       ccp->msgid_plural_pos = cp->msgid_plural_pos;
     }
@@ -3059,12 +3024,11 @@ arglist_parser_clone (struct arglist_parser *ap)
 
 
 void
-arglist_parser_remember_literal (struct arglist_parser *ap,
-                                 int argnum, char *string,
-                                 flag_context_ty context,
-                                 char *file_name, size_t line_number,
-                                 refcounted_string_list_ty *comment,
-                                 enum literalstring_escape_type type)
+arglist_parser_remember (struct arglist_parser *ap,
+                         int argnum, char *string,
+                         flag_context_ty context,
+                         char *file_name, size_t line_number,
+                         refcounted_string_list_ty *comment)
 {
   bool stored_string = false;
   size_t nalternatives = ap->nalternatives;
@@ -3079,7 +3043,6 @@ arglist_parser_remember_literal (struct arglist_parser *ap,
       if (argnum == cp->argnumc)
         {
           cp->msgctxt = string;
-          cp->msgctxt_escape = type;
           cp->msgctxt_pos.file_name = file_name;
           cp->msgctxt_pos.line_number = line_number;
           stored_string = true;
@@ -3091,7 +3054,6 @@ arglist_parser_remember_literal (struct arglist_parser *ap,
           if (argnum == cp->argnum1)
             {
               cp->msgid = string;
-              cp->msgid_escape = type;
               cp->msgid_context = context;
               cp->msgid_pos.file_name = file_name;
               cp->msgid_pos.line_number = line_number;
@@ -3103,7 +3065,6 @@ arglist_parser_remember_literal (struct arglist_parser *ap,
           if (argnum == cp->argnum2)
             {
               cp->msgid_plural = string;
-              cp->msgid_plural_escape = type;
               cp->msgid_plural_context = context;
               cp->msgid_plural_pos.file_name = file_name;
               cp->msgid_plural_pos.line_number = line_number;
@@ -3120,19 +3081,6 @@ arglist_parser_remember_literal (struct arglist_parser *ap,
 }
 
 
-void
-arglist_parser_remember (struct arglist_parser *ap,
-                         int argnum, char *string,
-                         flag_context_ty context,
-                         char *file_name, size_t line_number,
-                         refcounted_string_list_ty *comment)
-{
-  arglist_parser_remember_literal (ap, argnum, string, context,
-                                   file_name, line_number,
-                                   comment, LET_NONE);
-}
-
-
 void
 arglist_parser_remember_msgctxt (struct arglist_parser *ap,
                                  char *string,
@@ -3148,7 +3096,6 @@ arglist_parser_remember_msgctxt (struct arglist_parser *ap,
       struct partial_call *cp = &ap->alternative[i];
 
       cp->msgctxt = string;
-      cp->msgctxt_escape = LET_NONE;
       cp->msgctxt_pos.file_name = file_name;
       cp->msgctxt_pos.line_number = line_number;
       stored_string = true;
@@ -3401,8 +3348,6 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
           {
             flag_context_ty msgid_context = best_cp->msgid_context;
             flag_context_ty msgid_plural_context = best_cp->msgid_plural_context;
-            struct literalstring_parser *parser = current_literalstring_parser;
-            const char *encoding;
 
             /* Special support for the 3-argument tr operator in Qt:
                When --qt and --keyword=tr:1,1,2c,3t are specified, add to the
@@ -3416,98 +3361,15 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
                 msgid_plural_context.is_format3 = yes_according_to_context;
               }
 
-            if (best_cp->msgctxt != NULL)
-              {
-                if (parser != NULL && best_cp->msgctxt_escape != 0)
-                  {
-                    char *msgctxt =
-                      parser->parse (best_cp->msgctxt,
-                                     &best_cp->msgctxt_pos,
-                                     best_cp->msgctxt_escape);
-                    free (best_cp->msgctxt);
-                    best_cp->msgctxt = msgctxt;
-                  }
-                else
-                  {
-                    lex_pos_ty *pos = &best_cp->msgctxt_pos;
-                    CONVERT_STRING (best_cp->msgctxt, lc_string);
-                  }
-              }
-
-            if (parser != NULL && best_cp->msgid_escape != 0)
-              {
-                char *msgid = parser->parse (best_cp->msgid,
-                                             &best_cp->msgid_pos,
-                                             best_cp->msgid_escape);
-                if (best_cp->msgid_plural == best_cp->msgid)
-                  best_cp->msgid_plural = msgid;
-                free (best_cp->msgid);
-                best_cp->msgid = msgid;
-              }
-            else
-              {
-                lex_pos_ty *pos = &best_cp->msgid_pos;
-                CONVERT_STRING (best_cp->msgid, lc_string);
-              }
-
-            if (best_cp->msgid_plural)
-              {
-                /* best_cp->msgid_plural may point to best_cp->msgid.
-                   In that case, it is already interpreted and converted.  */
-                if (best_cp->msgid_plural != best_cp->msgid)
-                  {
-                    if (parser != NULL
-                        && best_cp->msgid_plural_escape != 0)
-                      {
-                        char *msgid_plural =
-                          parser->parse (best_cp->msgid_plural,
-                                         &best_cp->msgid_plural_pos,
-                                         best_cp->msgid_plural_escape);
-                        free (best_cp->msgid_plural);
-                        best_cp->msgid_plural = msgid_plural;
-                      }
-                    else
-                      {
-                        lex_pos_ty *pos = &best_cp->msgid_plural_pos;
-                        CONVERT_STRING (best_cp->msgid_plural, lc_string);
-                      }
-                  }
-
-                /* If best_cp->msgid_plural equals to best_cp->msgid,
-                   the ownership will be transferred to
-                   remember_a_message before it is passed to
-                   remember_a_message_plural.
-
-                   Make a copy of the string in that case.  */
-                if (best_cp->msgid_plural == best_cp->msgid)
-                  best_cp->msgid_plural = xstrdup (best_cp->msgid);
-              }
-
-            if (best_cp->msgid_comment != NULL)
-              {
-                refcounted_string_list_ty *msgid_comment =
-                  savable_comment_convert_encoding (best_cp->msgid_comment,
-                                                    &best_cp->msgid_pos);
-                drop_reference (best_cp->msgid_comment);
-                best_cp->msgid_comment = msgid_comment;
-              }
-
-            /* best_cp->msgctxt, best_cp->msgid, and best_cp->msgid_plural
-               are already in UTF-8.  Prevent further conversion in
-               remember_a_message.  */
-            encoding = xgettext_current_source_encoding;
-            xgettext_current_source_encoding = po_charset_utf8;
             mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid,
                                      msgid_context,
                                      &best_cp->msgid_pos,
                                      NULL, best_cp->msgid_comment);
             if (mp != NULL && best_cp->msgid_plural != NULL)
-              remember_a_message_plural (mp,
-                                         best_cp->msgid_plural,
+              remember_a_message_plural (mp, best_cp->msgid_plural,
                                          msgid_plural_context,
                                          &best_cp->msgid_plural_pos,
                                          NULL);
-            xgettext_current_source_encoding = encoding;
           }
 
           if (best_cp->xcomments.nitems > 0)
@@ -3906,7 +3768,6 @@ language_to_extractor (const char *name)
     flag_context_list_table_ty *flag_table;
     struct formatstring_parser *formatstring_parser1;
     struct formatstring_parser *formatstring_parser2;
-    struct literalstring_parser *literalstring_parser;
   };
   typedef struct table_ty table_ty;
 
@@ -3954,7 +3815,6 @@ language_to_extractor (const char *name)
         result.formatstring_parser1 = tp->formatstring_parser1;
         result.formatstring_parser2 = tp->formatstring_parser2;
         result.formatstring_parser3 = NULL;
-        result.literalstring_parser = tp->literalstring_parser;
 
         /* Handle --qt.  It's preferrable to handle this facility here rather
            than through an option --language=C++/Qt because the latter would
index 926881e37de8bc2fc85e84cf642ba79a2a751141..7c3712a9b9f9b38f04aa9a7ddbd0a270807b11ad 100644 (file)
@@ -242,25 +242,6 @@ extern refcounted_string_list_ty *savable_comment;
 extern void savable_comment_add (const char *str);
 extern void savable_comment_reset (void);
 
-/* Convert character encoding of COMMENT according to the current
-   source encoding.  Returns a new refcounted_string_list_ty.  */
-extern refcounted_string_list_ty *
-       savable_comment_convert_encoding (refcounted_string_list_ty *comment,
-                                         lex_pos_ty *pos);
-
-
-enum literalstring_escape_type
-{
-  LET_NONE = 0,
-  LET_ANSI_C = 1 << 0,
-  LET_UNICODE = 1 << 1
-};
-
-struct literalstring_parser
-{
-  char * (*parse) (const char *string, lex_pos_ty *pos,
-                   enum literalstring_escape_type type);
-};
 
 /* Add a message to the list of extracted messages.
    msgctxt must be either NULL or a malloc()ed string; its ownership is passed
@@ -294,6 +275,7 @@ extern void remember_a_message_plural (message_ty *mp,
                                        lex_pos_ty *pos,
                                        refcounted_string_list_ty *comment);
 
+
 /* Represents the progressive parsing of an argument list w.r.t. a single
    'struct callshape'.  */
 struct partial_call
@@ -306,15 +288,12 @@ struct partial_call
   int argtotal;                 /* total number of arguments, 0 if unspecified */
   string_list_ty xcomments;     /* auto-extracted comments */
   char *msgctxt;                /* context - owned string, or NULL */
-  enum literalstring_escape_type msgctxt_escape;
   lex_pos_ty msgctxt_pos;
   char *msgid;                  /* msgid - owned string, or NULL */
-  enum literalstring_escape_type msgid_escape;
   flag_context_ty msgid_context;
   lex_pos_ty msgid_pos;
   refcounted_string_list_ty *msgid_comment;
   char *msgid_plural;           /* msgid_plural - owned string, or NULL */
-  enum literalstring_escape_type msgid_plural_escape;
   flag_context_ty msgid_plural_context;
   lex_pos_ty msgid_plural_pos;
 };
@@ -348,19 +327,6 @@ extern void arglist_parser_remember (struct arglist_parser *ap,
                                      flag_context_ty context,
                                      char *file_name, size_t line_number,
                                      refcounted_string_list_ty *comment);
-/* Adds an uninterpreted string argument to an arglist_parser.  ARGNUM
-   must be > 0.
-   STRING is must be malloc()ed string; its ownership is passed to the callee.
-   FILE_NAME must be allocated with indefinite extent.
-   COMMENT may be savable_comment, or it may be a saved copy of savable_comment
-   (then add_reference must be used when saving it, and drop_reference while
-   dropping it).  Clear savable_comment.  */
-extern void arglist_parser_remember_literal (struct arglist_parser *ap,
-                                             int argnum, char *string,
-                                             flag_context_ty context,
-                                             char *file_name, size_t line_number,
-                                             refcounted_string_list_ty *comment,
-                                             enum literalstring_escape_type type);
 /* Adds a string argument as msgctxt to an arglist_parser, without incrementing
    the current argument number.
    STRING must be malloc()ed string; its ownership is passed to the callee.