]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
format-kde: Recognize KUIT markup
authorDaiki Ueno <ueno@gnu.org>
Thu, 5 Mar 2015 03:00:09 +0000 (12:00 +0900)
committerDaiki Ueno <ueno@gnu.org>
Mon, 9 Mar 2015 09:24:52 +0000 (18:24 +0900)
Reported by Chusslove Illich in:
https://lists.gnu.org/archive/html/bug-gettext/2015-01/msg00017.html
* gettext-tools/src/format.h (formatstring_kde_kuit): New variable
declaration.
* gettext-tools/src/format.c (formatstring_parsers): Register
formatstring_kde_kuitas a format string parser.
* gettext-tools/src/format-kde-kuit.c: New file.
* gettext-tools/src/message.h (NFORMATS): Increment.
(enum format_type): New enum value format_kde_kuit.
* gettext-tools/src/xgettext.c (xgettext_record_flag): Handle
format_kde_kuit.
* gettext-tools/src/Makefile.am (xgettext_SOURCES): Move
libexpat-compat.c to...
(libgettextsrc_la_SOURCES): ...here.
(xgettext_LDADD): Move @LTLIBEXPAT@ to...
(libgettextsrc_la_LDFLAGS): ...here.
(FORMAT_SOURCE): Add format-kde-kuit.c.
* gettext-tools/libgettextpo/Makefile.am (libgettextpo_la_AUXSOURCES):
Add ../src/format-kde-kuit.c and ../src/libexpat-compat.c.
(libgettextpo_la_LDFLAGS): Add @LTLIBEXPAT@.
* gettext-tools/tests/format-kde-kuit-1: New file.
* gettext-tools/tests/format-kde-kuit-2: New file.
* gettext-tools/tests/Makefile.am (TESTS): Add new tests.
* gettext-tools/doc/gettext.texi (kde-kuit-format): New subsection.
* NEWS: Mention KUIT format string support.

18 files changed:
ChangeLog
NEWS
gettext-tools/doc/ChangeLog
gettext-tools/doc/gettext.texi
gettext-tools/libgettextpo/ChangeLog
gettext-tools/libgettextpo/Makefile.am
gettext-tools/src/ChangeLog
gettext-tools/src/Makefile.am
gettext-tools/src/format-kde-kuit.c [new file with mode: 0644]
gettext-tools/src/format.c
gettext-tools/src/format.h
gettext-tools/src/message.c
gettext-tools/src/message.h
gettext-tools/src/xgettext.c
gettext-tools/tests/ChangeLog
gettext-tools/tests/Makefile.am
gettext-tools/tests/format-kde-kuit-1 [new file with mode: 0755]
gettext-tools/tests/format-kde-kuit-2 [new file with mode: 0755]

index d75bc60667f317ecbf9428d0256025c97d523b15..166c36b54633a9a4d99d5d5af59ad5918c384946 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-09  Daiki Ueno  <ueno@gnu.org>
+
+       * NEWS: Mention KUIT format string support.
+
 2015-03-04  Daiki Ueno  <ueno@gnu.org>
 
        build: Update libtool files to 2.4.6
diff --git a/NEWS b/NEWS
index 278a44424633d2cbb3e6e6b9da330b415677ce19..100f6d8bc8d4b85a7f1d46b6be548174445f48bf 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,11 @@ Version 0.19.5 - unreleased
   particularly improves "\N{...}" notation handling of xgettext for
   Perl and Python.
 
+* Programming languages support:
+  - C++ with KDE: xgettext and msgfmt can now recognize KUIT (KDE User
+    Interface Text) markup.  See the documentation section "KUIT
+    Format Strings" for more info.
+
 * Bug fixes:
   - xgettext C++11 raw string recognition is now stricter and don't
     accept unbalanced delimiters.
index bc0df95f7f8ed7453322e94a02246c9df6ef9782..1e1d46bc6a38ef6919817f015db3c70a99558025 100644 (file)
@@ -1,3 +1,7 @@
+2015-03-06  Daiki Ueno  <ueno@gnu.org>
+
+       * gettext.texi (kde-kuit-format): New subsection.
+
 2015-03-03  Daiki Ueno  <ueno@gnu.org>
 
        * xgettext.texi: Document options --check and --sentence-end.
index 366a646d99ac79cdadc8aa58b92415c9be7a18b2..ea0ae2b3e05cfcbf347262124dd6774841c39df9 100644 (file)
@@ -9063,6 +9063,7 @@ strings.
 * qt-format::                   Qt Format Strings
 * qt-plural-format::            Qt Plural Format Strings
 * kde-format::                  KDE Format Strings
+* kde-kuit-format::             KUIT Format Strings
 * boost-format::                Boost Format Strings
 * lua-format::                  Lua Format Strings
 * javascript-format::           JavaScript Format Strings
@@ -9311,7 +9312,7 @@ Qt format strings are described in the documentation of the QObject::tr method
 @uref{file:/usr/lib/qt-4.3.0/doc/html/qobject.html}.
 In summary, the only allowed directive is @samp{%n}.
 
-@node kde-format, boost-format, qt-plural-format, Translators for other Languages
+@node kde-format, kde-kuit-format, qt-plural-format, Translators for other Languages
 @subsection KDE Format Strings
 
 KDE 4 format strings are defined as follows:
@@ -9319,7 +9320,17 @@ A directive consists of a @samp{%} followed by a non-zero decimal number.
 If a @samp{%n} occurs in a format strings, all of @samp{%1}, ..., @samp{%(n-1)}
 must occur as well, except possibly one of them.
 
-@node boost-format, lua-format, kde-format, Translators for other Languages
+@node kde-kuit-format, boost-format, kde-format, Translators for other Languages
+@subsection KUIT Format Strings
+
+KUIT (KDE User Interface Text) is compatible with KDE 4 format strings,
+while it also allows programmers to add semantic information to a format
+string, through XML markup tags.  For example, if the first format
+directive is a filename, programmers could indicate that with
+@samp{<filename>%1</filename>}.  KUIT format strings are described in
+@uref{http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/prg_guide.html#kuit_markup}.
+
+@node boost-format, lua-format, kde-kuit-format, Translators for other Languages
 @subsection Boost Format Strings
 
 Boost format strings are described in the documentation of the
index c439706b4aefdbab7406185383d9b4e32c310ae1..f0f4bba440fd8bac8855c1374ee750f7e3258a21 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-06  Daiki Ueno  <ueno@gnu.org>
+
+       * Makefile.am (libgettextpo_la_AUXSOURCES): Add
+       ../src/format-kde-kuit.c and ../src/libexpat-compat.c.
+       (libgettextpo_la_LDFLAGS): Add @LTLIBEXPAT@.
+
 2014-12-24  Daiki Ueno  <ueno@gnu.org>
 
        * gettext 0.19.4 released.
index 10f5de653a14615bc092033c470f55201ec76b27..f49065be69317126fe0e4a4cdbd43f7d478649a7 100644 (file)
@@ -85,13 +85,15 @@ libgettextpo_la_AUXSOURCES = \
   ../src/format-qt.c \
   ../src/format-qt-plural.c \
   ../src/format-kde.c \
+  ../src/format-kde-kuit.c \
   ../src/format-boost.c \
   ../src/format-lua.c \
   ../src/format.c \
   ../src/plural-exp.c \
   ../src/plural-eval.c \
   ../src/msgl-check.c \
-  ../src/sentence.c
+  ../src/sentence.c \
+  ../src/libexpat-compat.c
 
 # Libtool's library version information for libgettextpo.
 # See the libtool documentation, section "Library interface versions".
@@ -106,7 +108,7 @@ libgettextpo_la_LIBADD = libgnu.la $(WOE32_LIBADD) $(LTLIBUNISTRING)
 libgettextpo_la_LDFLAGS = \
   -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \
   -rpath $(libdir) \
-  @LTLIBINTL@ @LTLIBICONV@ -lc -no-undefined
+  @LTLIBINTL@ @LTLIBICONV@ @LTLIBEXPAT@ -lc -no-undefined
 
 # Tell the mingw or Cygwin linker which symbols to export.
 if WOE32DLL
index 754a9dcdca3a6fe65ede6c832f77f05b58a2069d..d1cc42f18201b2fd9e2057d7109b9139495ad22c 100644 (file)
@@ -1,3 +1,21 @@
+2015-03-06  Daiki Ueno  <ueno@gnu.org>
+
+       format-kde: Recognize KUIT markup
+       Reported by Chusslove Illich in:
+       https://lists.gnu.org/archive/html/bug-gettext/2015-01/msg00017.html
+       * format.h (formatstring_kde_kuit): New variable declaration.
+       * format.c (formatstring_parsers): Register formatstring_kde_kuit
+       as a format string parser.
+       * format-kde-kuit.c: New file.
+       * message.h (NFORMATS): Increment.
+       (enum format_type): New enum value format_kde_kuit.
+       * xgettext.c (xgettext_record_flag): Handle format_kde_kuit.
+       * Makefile.am (xgettext_SOURCES): Move libexpat-compat.c to...
+       (libgettextsrc_la_SOURCES): ...here.
+       (xgettext_LDADD): Move @LTLIBEXPAT@ to...
+       (libgettextsrc_la_LDFLAGS): ...here.
+       (FORMAT_SOURCE): Add format-kde-kuit.c.
+
 2015-03-02  Daiki Ueno  <ueno@gnu.org>
 
        xgettext: Support message syntax checks
index edb376f9462ff02c0143775dcc03f8095da1750f..9a23be0c557a1ff6cb3c2c4e6ea9ff9817597276 100644 (file)
@@ -138,6 +138,7 @@ FORMAT_SOURCE += \
   format-qt.c \
   format-qt-plural.c \
   format-kde.c \
+  format-kde-kuit.c \
   format-boost.c \
   format-lua.c \
   format-javascript.c
@@ -148,7 +149,7 @@ $(COMMON_SOURCE) read-catalog.c \
 color.c write-catalog.c write-properties.c write-stringtable.c write-po.c \
 msgl-ascii.c msgl-iconv.c msgl-equal.c msgl-cat.c msgl-header.c msgl-english.c \
 msgl-check.c file-list.c msgl-charset.c po-time.c plural-exp.c plural-eval.c \
-plural-table.c quote.h sentence.h sentence.c \
+plural-table.c quote.h sentence.h sentence.c libexpat-compat.c \
 $(FORMAT_SOURCE) \
 read-desktop.c
 
@@ -180,7 +181,6 @@ xgettext_SOURCES += \
   x-c.c x-po.c x-sh.c x-python.c x-lisp.c x-elisp.c x-librep.c x-scheme.c \
   x-smalltalk.c x-java.c x-csharp.c x-awk.c x-ycp.c x-tcl.c x-perl.c x-php.c \
   x-rst.c x-glade.c x-lua.c x-javascript.c x-vala.c x-gsettings.c \
-  libexpat-compat.c \
   x-desktop.c
 if !WOE32DLL
 msgattrib_SOURCES = msgattrib.c
@@ -247,7 +247,7 @@ urlget_SOURCES = urlget.c
 # use iconv().
 libgettextsrc_la_LDFLAGS = \
   -release @VERSION@ \
-  ../gnulib-lib/libgettextlib.la $(LTLIBUNISTRING) @LTLIBINTL@ @LTLIBICONV@ -lc -no-undefined
+  ../gnulib-lib/libgettextlib.la $(LTLIBUNISTRING) @LTLIBINTL@ @LTLIBICONV@ @LTLIBEXPAT@ -lc -no-undefined
 
 libgettextsrc_la_CPPFLAGS = $(AM_CPPFLAGS)
 
@@ -278,7 +278,7 @@ msgcmp_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ @MSGMERGE_LIBM@ $(WOE32_LDADD
 msgfmt_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ $(WOE32_LDADD)
 msgmerge_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ @MSGMERGE_LIBM@ $(WOE32_LDADD) $(OPENMP_CFLAGS)
 msgunfmt_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ $(WOE32_LDADD)
-xgettext_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ @LTLIBEXPAT@ @LTLIBICONV@ $(WOE32_LDADD)
+xgettext_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ @LTLIBICONV@ $(WOE32_LDADD)
 msgattrib_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ $(WOE32_LDADD)
 msgcat_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ $(WOE32_LDADD)
 msgcomm_LDADD = libgettextsrc.la @INTL_MACOSX_LIBS@ $(WOE32_LDADD)
diff --git a/gettext-tools/src/format-kde-kuit.c b/gettext-tools/src/format-kde-kuit.c
new file mode 100644 (file)
index 0000000..9584659
--- /dev/null
@@ -0,0 +1,391 @@
+/* KUIT (KDE UI Text) format strings.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   Written by Daiki Ueno <ueno@gnu.org>, 2015.
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "format.h"
+#include "libexpat-compat.h"
+#include "unistr.h"
+#include "xalloc.h"
+#include "xvasprintf.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
+
+
+/* KUIT (KDE User Interface Text) is an XML-like markup which augments
+   translatable strings with semantic information:
+   http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/prg_guide.html#kuit_markup
+   KUIT can be seen as a fragment of well-formed XML, except that it
+   still allows '&' as a Qt accelerator marker and '%' as a format
+   directive.  */
+
+struct spec
+{
+  /* A format string descriptor returned from formatstring_kde.parse.  */
+  void *base;
+};
+
+#if DYNLOAD_LIBEXPAT || HAVE_LIBEXPAT
+
+/* Callback called when <element> is seen.  */
+static void
+start_element_handler (void *data, const char *name,
+                       const char **attributes)
+{
+  /* Nothing to do for now.  We could check text outside of a
+     structuring tag, etc.  */
+}
+
+/* Callback called when </element> is seen.  */
+static void
+end_element_handler (void *data, const char *name)
+{
+  /* Nothing to do.  */
+}
+
+struct char_range
+{
+  ucs4_t start;
+  ucs4_t end;
+};
+
+/* Character ranges for NameStartChar defined in:
+   http://www.w3.org/TR/REC-xml/#NT-NameStartChar  */
+static const struct char_range name_chars1[] =
+  {
+    { ':', ':' },
+    { 'A', 'Z' },
+    { '_', '_' },
+    { 'a', 'z' },
+    { 0xC0, 0xD6 },
+    { 0xD8, 0xF6 },
+    { 0xF8, 0x2FF },
+    { 0x370, 0x37D },
+    { 0x37F, 0x1FFF },
+    { 0x200C, 0x200D },
+    { 0x2070, 0x218F },
+    { 0x2C00, 0x2FEF },
+    { 0x3001, 0xD7FF },
+    { 0xF900, 0xFDCF },
+    { 0xFDF0, 0xFFFD },
+    { 0x10000, 0xEFFFF }
+  };
+
+/* Character ranges for NameChar, excluding NameStartChar:
+   http://www.w3.org/TR/REC-xml/#NT-NameChar  */
+static const struct char_range name_chars2[] =
+  {
+    { '-', '-' },
+    { '.', '.' },
+    { '0', '9' },
+    { 0xB7, 0xB7 },
+    { 0x0300, 0x036F },
+    { 0x203F, 0x2040 }
+  };
+
+/* Return true if INPUT is an XML reference.  */
+static bool
+is_reference (const char *input)
+{
+  const char *str = input;
+  const char *str_limit = str + strlen (input);
+  ucs4_t uc;
+  int i;
+
+  str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+  assert (uc == '&');
+
+  str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+
+  /* CharRef */
+  if (uc == '#')
+    {
+      str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+      if (uc == 'x')
+        {
+          while (str < str_limit)
+            {
+              str += u8_mbtouc (&uc, (const unsigned char *) str,
+                                str_limit - str);
+              if (!(('0' <= uc && uc <= '9')
+                    || ('A' <= uc && uc <= 'F')
+                    || ('a' <= uc && uc <= 'f')))
+                break;
+            }
+          return uc == ';';
+        }
+      else if ('0' <= uc && uc <= '9')
+        {
+          while (str < str_limit)
+            {
+              str += u8_mbtouc (&uc, (const unsigned char *) str,
+                                str_limit - str);
+              if (!('0' <= uc && uc <= '9'))
+                break;
+            }
+          return uc == ';';
+        }
+    }
+  else
+    {
+      /* EntityRef */
+      for (i = 0; i < SIZEOF (name_chars1); i++)
+        if (name_chars1[i].start <= uc && uc <= name_chars1[i].end)
+          break;
+
+      if (i == SIZEOF (name_chars1))
+        return false;
+
+      while (str < str_limit)
+        {
+          str += u8_mbtouc (&uc, (const unsigned char *) str, str_limit - str);
+          for (i = 0; i < SIZEOF (name_chars1); i++)
+            if (name_chars1[i].start <= uc && uc <= name_chars1[i].end)
+              break;
+          if (i == SIZEOF (name_chars1))
+            {
+              for (i = 0; i < SIZEOF (name_chars2); i++)
+                if (name_chars2[i].start <= uc && uc <= name_chars2[i].end)
+                  break;
+              if (i == SIZEOF (name_chars2))
+                return false;
+            }
+        }
+      return uc == ';';
+    }
+
+  return false;
+}
+
+#endif
+
+
+static void *
+format_parse (const char *format, bool translated, char *fdi,
+              char **invalid_reason)
+{
+  struct spec spec;
+  struct spec *result;
+
+  spec.base = NULL;
+
+#if DYNLOAD_LIBEXPAT || HAVE_LIBEXPAT
+  if (LIBEXPAT_AVAILABLE ())
+    {
+      XML_Parser parser;
+      const char *str = format;
+      const char *str_limit = str + strlen (format);
+      size_t amp_count;
+      char *buffer, *bp;
+
+      for (amp_count = 0; str < str_limit; amp_count++)
+        {
+          const char *amp = strchrnul (str, '&');
+          if (*amp != '&')
+            break;
+          str = amp + 1;
+        }
+
+      buffer = xmalloc (amp_count * 4 + strlen (format) + 16);
+      *buffer = '\0';
+
+      bp = buffer;
+      bp = stpcpy (bp, "<kuit>");
+      str = format;
+      while (str < str_limit)
+        {
+          const char *amp = strchrnul (str, '&');
+
+          bp = stpncpy (bp, str, amp - str);
+          if (*amp != '&')
+            break;
+
+          bp = stpcpy (bp, is_reference (amp) ? "&" : "&amp;");
+          str = amp + 1;
+        }
+      bp = stpcpy (bp, "</kuit>");
+
+      parser = XML_ParserCreate (NULL);
+      if (parser == NULL)
+        {
+          *invalid_reason = xasprintf (_("memory exhausted"));
+          free (buffer);
+          return NULL;
+        }
+
+      XML_SetElementHandler (parser,
+                             start_element_handler,
+                             end_element_handler);
+
+      if (XML_Parse (parser, buffer, strlen (buffer), 0) == 0)
+        {
+          *invalid_reason =
+            xasprintf (_("error while parsing: %s"),
+                       XML_ErrorString (XML_GetErrorCode (parser)));
+          free (buffer);
+          XML_ParserFree (parser);
+          return NULL;
+        }
+
+      if (XML_Parse (parser, NULL, 0, 1) == 0)
+        {
+          *invalid_reason =
+            xasprintf (_("error while parsing: %s"),
+                       XML_ErrorString (XML_GetErrorCode (parser)));
+          free (buffer);
+          XML_ParserFree (parser);
+          return NULL;
+        }
+
+      free (buffer);
+      XML_ParserFree (parser);
+    }
+#endif
+
+  spec.base = formatstring_kde.parse (format, translated, fdi, invalid_reason);
+  if (spec.base == NULL)
+    return NULL;
+
+  result = XMALLOC (struct spec);
+  *result = spec;
+  return result;
+}
+
+static void
+format_free (void *descr)
+{
+  struct spec *spec = descr;
+  formatstring_kde.free (spec->base);
+  free (spec);
+}
+
+static int
+format_get_number_of_directives (void *descr)
+{
+  struct spec *spec = descr;
+  return formatstring_kde.get_number_of_directives (spec->base);
+}
+
+static bool
+format_check (void *msgid_descr, void *msgstr_descr, bool equality,
+              formatstring_error_logger_t error_logger,
+              const char *pretty_msgid, const char *pretty_msgstr)
+{
+  struct spec *msgid_spec = msgid_descr;
+  struct spec *msgstr_spec = msgstr_descr;
+
+  return formatstring_kde.check (msgid_spec->base, msgstr_spec->base, equality,
+                                 error_logger,
+                                 pretty_msgid, pretty_msgstr);
+}
+
+struct formatstring_parser formatstring_kde_kuit =
+{
+  format_parse,
+  format_free,
+  format_get_number_of_directives,
+  NULL,
+  format_check
+};
+
+
+#ifdef TEST
+
+/* Test program: Print the argument list specification returned by
+   format_parse for strings read from standard input.  */
+
+#include <stdio.h>
+
+static void
+format_print (void *descr)
+{
+  struct spec *spec = (struct spec *) descr;
+  unsigned int last;
+  unsigned int i;
+
+  if (spec == NULL)
+    {
+      printf ("INVALID");
+      return;
+    }
+
+  printf ("(");
+  last = 1;
+  for (i = 0; i < spec->numbered_arg_count; i++)
+    {
+      unsigned int number = spec->numbered[i].number;
+
+      if (i > 0)
+        printf (" ");
+      if (number < last)
+        abort ();
+      for (; last < number; last++)
+        printf ("_ ");
+      last = number + 1;
+    }
+  printf (")");
+}
+
+int
+main ()
+{
+  for (;;)
+    {
+      char *line = NULL;
+      size_t line_size = 0;
+      int line_len;
+      char *invalid_reason;
+      void *descr;
+
+      line_len = getline (&line, &line_size, stdin);
+      if (line_len < 0)
+        break;
+      if (line_len > 0 && line[line_len - 1] == '\n')
+        line[--line_len] = '\0';
+
+      invalid_reason = NULL;
+      descr = format_parse (line, false, NULL, &invalid_reason);
+
+      format_print (descr);
+      printf ("\n");
+      if (descr == NULL)
+        printf ("%s\n", invalid_reason);
+
+      free (invalid_reason);
+      free (line);
+    }
+
+  return 0;
+}
+
+/*
+ * For Emacs M-x compile
+ * Local Variables:
+ * compile-command: "/bin/sh ../libtool --tag=CC --mode=link gcc -o a.out -static -O -g -Wall -I.. -I../gnulib-lib -I../intl -DHAVE_CONFIG_H -DTEST format-kde-kuit.c ../gnulib-lib/libgettextlib.la"
+ * End:
+ */
+
+#endif /* TEST */
index c73ad7de9d077e122b0e69f5a53522d3ff31d905..cb5f49bdd49c3005f088a71f35473df7c7e87681 100644 (file)
@@ -58,6 +58,7 @@ struct formatstring_parser *formatstring_parsers[NFORMATS] =
   /* format_qt */               &formatstring_qt,
   /* format_qt_plural */        &formatstring_qt_plural,
   /* format_kde */              &formatstring_kde,
+  /* format_kde_kuit */         &formatstring_kde_kuit,
   /* format_boost */            &formatstring_boost,
   /* format_lua */              &formatstring_lua,
   /* format_javascript */       &formatstring_javascript
index d92532ddffe0ce1c169d3bd369365ed1e1e218c6..3214a9df1b376b103194291fe42936bd99924e79 100644 (file)
@@ -119,6 +119,7 @@ extern DLL_VARIABLE struct formatstring_parser formatstring_gfc_internal;
 extern DLL_VARIABLE struct formatstring_parser formatstring_qt;
 extern DLL_VARIABLE struct formatstring_parser formatstring_qt_plural;
 extern DLL_VARIABLE struct formatstring_parser formatstring_kde;
+extern DLL_VARIABLE struct formatstring_parser formatstring_kde_kuit;
 extern DLL_VARIABLE struct formatstring_parser formatstring_boost;
 extern DLL_VARIABLE struct formatstring_parser formatstring_lua;
 extern DLL_VARIABLE struct formatstring_parser formatstring_javascript;
index 2596887a419de79ae175de29b22159d3cdd89043..00372a2d99c4d5bb4455ca63c24a5533b9135e33 100644 (file)
@@ -58,6 +58,7 @@ const char *const format_language[NFORMATS] =
   /* format_qt */               "qt",
   /* format_qt_plursl */        "qt-plural",
   /* format_kde */              "kde",
+  /* format_kde_kuit */         "kde-kuit",
   /* format_boost */            "boost",
   /* format_lua */              "lua",
   /* format_javascript */       "javascript"
@@ -89,6 +90,7 @@ const char *const format_language_pretty[NFORMATS] =
   /* format_qt */               "Qt",
   /* format_qt_plural */        "Qt plural",
   /* format_kde */              "KDE",
+  /* format_kde_kuit */         "KDE KUIT",
   /* format_boost */            "Boost",
   /* format_lua */              "Lua",
   /* format_javascript */       "JavaScript"
index 8b9bc3f6e1c06ff5fbe98a0e37d40cc45dd4cbae..3649e1b4a19091a7a6542ae361f266843a3e8c0c 100644 (file)
@@ -67,11 +67,12 @@ enum format_type
   format_qt,
   format_qt_plural,
   format_kde,
+  format_kde_kuit,
   format_boost,
   format_lua,
   format_javascript
 };
-#define NFORMATS 27     /* Number of format_type enum values.  */
+#define NFORMATS 28     /* Number of format_type enum values.  */
 extern DLL_VARIABLE const char *const format_language[NFORMATS];
 extern DLL_VARIABLE const char *const format_language_pretty[NFORMATS];
 
index 310b349710f66dccbeab6f15af73287b047827ec..1c9830e19703c9cdecb8ca2c476b7b0727c2697d 100644 (file)
@@ -1864,6 +1864,11 @@ xgettext_record_flag (const char *optionstring)
                                                     name_start, name_end,
                                                     argnum, value, pass);
                     break;
+                  case format_kde_kuit:
+                    flag_context_list_table_insert (&flag_table_cxx_kde, 2,
+                                                    name_start, name_end,
+                                                    argnum, value, pass);
+                    break;
                   case format_boost:
                     flag_context_list_table_insert (&flag_table_cxx_boost, 1,
                                                     name_start, name_end,
@@ -2543,7 +2548,19 @@ meta information, not the empty string.\n")));
                && (possible_format_p (is_format[format_qt])
                    || possible_format_p (is_format[format_qt_plural])
                    || possible_format_p (is_format[format_kde])
-                   || possible_format_p (is_format[format_boost]))))
+                   || possible_format_p (is_format[format_kde_kuit])
+                   || possible_format_p (is_format[format_boost])))
+          /* Avoid flagging a string as kde-format when it's known to
+             be a kde-kuit-format string.  */
+          && !(i == format_kde
+               && possible_format_p (is_format[format_kde_kuit]))
+          /* Avoid flagging a string as kde-kuit-format when it's
+             known to be a kde-format string.  Note that this relies
+             on the fact that format_kde < format_kde_kuit, so a
+             string will be marked as kde-format if both are
+             undecided.  */
+          && !(i == format_kde_kuit
+               && possible_format_p (is_format[format_kde])))
         {
           struct formatstring_parser *parser = formatstring_parsers[i];
           char *invalid_reason = NULL;
@@ -2678,7 +2695,19 @@ remember_a_message_plural (message_ty *mp, char *string,
                  && (possible_format_p (mp->is_format[format_qt])
                      || possible_format_p (mp->is_format[format_qt_plural])
                      || possible_format_p (mp->is_format[format_kde])
-                     || possible_format_p (mp->is_format[format_boost]))))
+                     || possible_format_p (mp->is_format[format_kde_kuit])
+                     || possible_format_p (mp->is_format[format_boost])))
+            /* Avoid flagging a string as kde-format when it's known
+               to be a kde-kuit-format string.  */
+            && !(i == format_kde
+                 && possible_format_p (mp->is_format[format_kde_kuit]))
+            /* Avoid flagging a string as kde-kuit-format when it's
+               known to be a kde-format string.  Note that this relies
+               on the fact that format_kde < format_kde_kuit, so a
+               string will be marked as kde-format if both are
+               undecided.  */
+            && !(i == format_kde_kuit
+                 && possible_format_p (mp->is_format[format_kde])))
           {
             struct formatstring_parser *parser = formatstring_parsers[i];
             char *invalid_reason = NULL;
@@ -3706,6 +3735,7 @@ language_to_extractor (const char *name)
           {
             result.flag_table = &flag_table_cxx_kde;
             result.formatstring_parser2 = &formatstring_kde;
+            result.formatstring_parser3 = &formatstring_kde_kuit;
           }
         /* Likewise for --boost.  */
         if (recognize_format_boost && strcmp (tp->name, "C++") == 0)
index 1ba2935649a8bcf1dd50ffb9195d8bcfa2cf4227..72a46d451cdf4a9a98ac8176c15302459d6234fe 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-05  Daiki Ueno  <ueno@gnu.org>
+
+       * format-kde-kuit-1: New file.
+       * format-kde-kuit-2: New file.
+       * Makefile.am (TESTS): Add new tests.
+
 2015-03-03  Daiki Ueno  <ueno@gnu.org>
 
        * xgettext-14: New file.
index ea8bfa96f75fd2a35a4d5515f641767b7ffd7cd5..a4decaf762ea99bb35ffd9f21e9756420e67620b 100644 (file)
@@ -119,6 +119,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
        format-gfc-internal-1 format-gfc-internal-2 \
        format-java-1 format-java-2 \
        format-kde-1 format-kde-2 \
+       format-kde-kuit-1 format-kde-kuit-2 \
        format-librep-1 format-librep-2 \
        format-lisp-1 format-lisp-2 \
        format-php-1 format-php-2 \
diff --git a/gettext-tools/tests/format-kde-kuit-1 b/gettext-tools/tests/format-kde-kuit-1
new file mode 100755 (executable)
index 0000000..a63ff3d
--- /dev/null
@@ -0,0 +1,61 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test recognition of KUIT format strings.
+
+cat <<\EOF > f-kd-1.data
+# Unrecognized: unbalanced filename tag
+"<filename>a"
+# Unrecognized: unbalanced filename tag
+"<filename>%1"
+# Unrecognized: unbalanced filename tag
+"<filename>%1</xfilename>"
+# Valid: one argument
+"<filename>%1</filename>"
+# Valid: accelerator
+"<command>&Application.About</command>"
+# Valid: accelerator at the end
+"<command>About</command>&A"
+# Valid: accelerator
+"<command>&/</command>"
+# Valid: entity reference
+"<command>&amp;About</command>"
+# Valid: character reference
+"<command>&#x2A;&#x2a;&#x61;&#141;</command>"
+EOF
+
+: ${XGETTEXT=xgettext}
+n=0
+while read comment; do
+  read string
+  n=`expr $n + 1`
+  cat <<EOF > f-kd-1-$n.in
+xi18n(${string});
+EOF
+  ${XGETTEXT} -L C++ --kde --flag=xi18n:1:kde-kuit-format --flag=i18n:1:kde-format -kxi18n -ki18n -o f-kd-1-$n.po f-kd-1-$n.in || exit 1
+  test -f f-kd-1-$n.po || exit 1
+  fail=
+  if echo "$comment" | grep 'Valid:' > /dev/null; then
+    if grep kde-kuit-format f-kd-1-$n.po > /dev/null; then
+      :
+    else
+      fail=yes
+    fi
+  else
+    if grep kde-kuit-format f-kd-1-$n.po > /dev/null; then
+      fail=yes
+    else
+      :
+    fi
+  fi
+  if test -n "$fail"; then
+    echo "Format string recognition error:" 1>&2
+    cat f-kd-1-$n.in 1>&2
+    echo "Got:" 1>&2
+    cat f-kd-1-$n.po 1>&2
+    exit 1
+  fi
+  rm -f f-kd-1-$n.in f-kd-1-$n.po
+done < f-kd-1.data
+
+exit 0
diff --git a/gettext-tools/tests/format-kde-kuit-2 b/gettext-tools/tests/format-kde-kuit-2
new file mode 100755 (executable)
index 0000000..b2653d1
--- /dev/null
@@ -0,0 +1,67 @@
+#! /bin/sh
+. "${srcdir=.}/init.sh"; path_prepend_ . ../src
+
+# Test checking of KDE KUIT format strings.
+
+cat <<\EOF > f-kd-2.data
+# Valid: one argument
+msgid "<filename>%1</filename>"
+msgstr "<filename>%1</filename>"
+# Invalid: missing argument
+msgid "<filename>%1</filename>"
+msgstr "<filename>foo</filename>"
+# Valid: change the text
+msgid "<filename>foo</filename>"
+msgstr "<filename>bar</filename>"
+# Invalid: unbalanced tag
+msgid "<filename>foo</filename>"
+msgstr "<filename>bar"
+# Invalid: unbalanced tag
+msgid "<filename>foo</filename>"
+msgstr "<filename>bar</xfilename>"
+# Valid: replaced tag
+msgid "<filename>foo</filename>"
+msgstr "<foo>foo</foo>"
+# Valid: accelerator
+msgid "<filename>&foo</filename>"
+msgstr "<foo>&foo</foo>"
+# Valid: entity reference
+msgid "<filename>foo</filename>"
+msgstr "<foo>&amp;</foo>"
+EOF
+
+: ${MSGFMT=msgfmt}
+n=0
+while read comment; do
+  read msgid_line
+  read msgstr_line
+  n=`expr $n + 1`
+  cat <<EOF > f-kd-2-$n.po
+#, kde-kuit-format
+${msgid_line}
+${msgstr_line}
+EOF
+  fail=
+  if echo "$comment" | grep 'Valid:' > /dev/null; then
+    if ${MSGFMT} --check-format -o f-kd-2-$n.mo f-kd-2-$n.po; then
+      :
+    else
+      fail=yes
+    fi
+  else
+    ${MSGFMT} --check-format -o f-kd-2-$n.mo f-kd-2-$n.po 2> /dev/null
+    if test $? = 1; then
+      :
+    else
+      fail=yes
+    fi
+  fi
+  if test -n "$fail"; then
+    echo "Format string checking error:" 1>&2
+    cat f-kd-2-$n.po 1>&2
+    exit 1
+  fi
+  rm -f f-kd-2-$n.po f-kd-2-$n.mo
+done < f-kd-2.data
+
+exit 0