Re: gettext, plural form and translation - Mailing list pgsql-hackers

From Sergey Burladyan
Subject Re: gettext, plural form and translation
Date
Msg-id 87ocvvg5ne.fsf@seb.progtech.ru
Whole thread Raw
In response to Re: gettext, plural form and translation  (Alvaro Herrera <alvherre@commandprompt.com>)
Responses Re: gettext, plural form and translation  (Sergey Burladyan <eshkinkot@gmail.com>)
Re: gettext, plural form and translation  (Peter Eisentraut <peter_e@gmx.net>)
List pgsql-hackers
Alvaro Herrera <alvherre@commandprompt.com> writes:

> Care to submit a patch?

this is it, i divide it into two, first is change source and second is change
ru.po file for psql.

changelog:

 gettext-plural-test.patch
 - check ngettext in configure (HAVE_NGETTEXT), show warning if not. must be
 error, i agree with Peter, i think gettext without support of plural form can't
 compile .po file with it :(, but not sure, so for test it is only warning
 - new macros _P(s,p,n) for ngettext
 - HAVE_NGETTEXT always 1 in pg_config.h.win32
 - psql, remove "(1 row)", switch this string into _P(...) macros

 gettext-plural-ru-test.patch:
 - correct translation for "1 rows" message

*** a/config/programs.m4
--- b/config/programs.m4
***************
*** 193,198 **** AC_DEFUN([PGAC_CHECK_GETTEXT],
--- 193,202 ----
  [
    AC_SEARCH_LIBS(bind_textdomain_codeset, intl, [],
                   [AC_MSG_ERROR([a gettext implementation is required for NLS])])
+   AC_SEARCH_LIBS(ngettext, intl,
+                  [AC_DEFINE(HAVE_NGETTEXT, 1,
+                             [Define to 1 if you have the ngettext function.])],
+                  [AC_MSG_WARN([NLS broken, plural forms support required for compile .po files])])
    AC_CHECK_HEADER([libintl.h], [],
                    [AC_MSG_ERROR([header file <libintl.h> is required for NLS])])
    AC_CHECK_PROGS(MSGFMT, msgfmt)
*** a/configure
--- b/configure
***************
*** 26022,26027 **** echo "$as_me: error: a gettext implementation is required for NLS" >&2;}
--- 26022,26117 ----
     { (exit 1); exit 1; }; }
  fi

+   { echo "$as_me:$LINENO: checking for library containing ngettext" >&5
+ echo $ECHO_N "checking for library containing ngettext... $ECHO_C" >&6; }
+ if test "${ac_cv_search_ngettext+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   ac_func_search_save_LIBS=$LIBS
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+
+ /* Override any GCC internal prototype to avoid an error.
+    Use char because int might match the return type of a GCC
+    builtin and then its argument prototype would still apply.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char ngettext ();
+ int
+ main ()
+ {
+ return ngettext ();
+   ;
+   return 0;
+ }
+ _ACEOF
+ for ac_lib in '' intl; do
+   if test -z "$ac_lib"; then
+     ac_res="none required"
+   else
+     ac_res=-l$ac_lib
+     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+   fi
+   rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+      test -z "$ac_c_werror_flag" ||
+      test ! -s conftest.err
+        } && test -s conftest$ac_exeext &&
+        $as_test_x conftest$ac_exeext; then
+   ac_cv_search_ngettext=$ac_res
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+
+ fi
+
+ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+       conftest$ac_exeext
+   if test "${ac_cv_search_ngettext+set}" = set; then
+   break
+ fi
+ done
+ if test "${ac_cv_search_ngettext+set}" = set; then
+   :
+ else
+   ac_cv_search_ngettext=no
+ fi
+ rm conftest.$ac_ext
+ LIBS=$ac_func_search_save_LIBS
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_search_ngettext" >&5
+ echo "${ECHO_T}$ac_cv_search_ngettext" >&6; }
+ ac_res=$ac_cv_search_ngettext
+ if test "$ac_res" != no; then
+   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+ cat >>confdefs.h <<\_ACEOF
+ #define HAVE_NGETTEXT 1
+ _ACEOF
+
+ else
+   { echo "$as_me:$LINENO: WARNING: NLS broken, plural forms support required for compile .po files" >&5
+ echo "$as_me: WARNING: NLS broken, plural forms support required for compile .po files" >&2;}
+ fi
+
    if test "${ac_cv_header_libintl_h+set}" = set; then
    { echo "$as_me:$LINENO: checking for libintl.h" >&5
  echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6; }
*** a/src/bin/psql/print.c
--- b/src/bin/psql/print.c
***************
*** 2348,2357 **** printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f
          char        default_footer[100];

          total_records = opt->topt.prior_records + cont.nrows;
!         if (total_records == 1)
!             snprintf(default_footer, 100, _("(1 row)"));
!         else
!             snprintf(default_footer, 100, _("(%lu rows)"), total_records);

          printTableAddFooter(&cont, default_footer);
      }
--- 2348,2354 ----
          char        default_footer[100];

          total_records = opt->topt.prior_records + cont.nrows;
!         snprintf(default_footer, 100, _P("(%lu row)", "(%lu rows)", total_records), total_records);

          printTableAddFooter(&cont, default_footer);
      }
*** a/src/include/c.h
--- b/src/include/c.h
***************
*** 91,102 ****
--- 91,108 ----
  #include <locale.h>

  #define _(x) gettext(x)
+ #ifdef HAVE_NGETTEXT
+ #define _P(s,p,n) ngettext(s,p,n)
+ #else
+ #define _P(s,p,n) ((n) == 1 ? (s) : (p))
+ #endif

  #ifdef ENABLE_NLS
  #include <libintl.h>
  #else
  #define gettext(x) (x)
  #define dgettext(d,x) (x)
+ #define ngettext(s,p,n) ((n) == 1 ? (s) : (p))
  #endif

  /*
*** a/src/include/pg_config.h.in
--- b/src/include/pg_config.h.in
***************
*** 321,326 ****
--- 321,329 ----
  /* Define to 1 if you have the <netinet/tcp.h> header file. */
  #undef HAVE_NETINET_TCP_H

+ /* Define to 1 if you have the ngettext function. */
+ #undef HAVE_NGETTEXT
+
  /* Define to 1 if you have the `on_exit' function. */
  #undef HAVE_ON_EXIT

*** a/src/include/pg_config.h.win32
--- b/src/include/pg_config.h.win32
***************
*** 267,272 ****
--- 267,275 ----
  /* Define to 1 if you have the <netinet/tcp.h> header file. */
  /* #undef HAVE_NETINET_TCP_H */

+ /* Define to 1 if you have the 'ngettext' function. */
+ #define HAVE_NGETTEXT 1
+
  /* Define to 1 if you have the `on_exit' function. */
  /* #undef HAVE_ON_EXIT */

*** a/src/bin/psql/po/ru.po
--- b/src/bin/psql/po/ru.po
***************
*** 19,25 **** msgid ""
  msgstr ""
  "Project-Id-Version: PostgreSQL 8.0\n"
  "POT-Creation-Date: 2005-01-17 19:06+0000\n"
! "PO-Revision-Date: 2005-01-17 15:36-0500\n"
  "Last-Translator: Serguei A. Mokhov <mokhov@cs.concordia.ca>\n"
  "Language-Team: pgsql-ru-general <pgsql-ru-general@postgresql.org>\n"
  "MIME-Version: 1.0\n"
--- 19,25 ----
  msgstr ""
  "Project-Id-Version: PostgreSQL 8.0\n"
  "POT-Creation-Date: 2005-01-17 19:06+0000\n"
! "PO-Revision-Date: 2009-03-20 05:19+0300\n"
  "Last-Translator: Serguei A. Mokhov <mokhov@cs.concordia.ca>\n"
  "Language-Team: pgsql-ru-general <pgsql-ru-general@postgresql.org>\n"
  "MIME-Version: 1.0\n"
***************
*** 27,32 **** msgstr ""
--- 27,34 ----
  "Content-Transfer-Encoding: 8bit\n"
  "X-Poedit-Language: Russian\n"
  "X-Poedit-Country: RUSSIAN FEDERATION\n"
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+ "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"

  #: command.c:116
  msgid "Warning: This syntax is deprecated.\n"
***************
*** 930,943 **** msgstr "
  msgid "(No rows)\n"
  msgstr "(Нет записей)\n"

! #: print.c:1200
! msgid "(1 row)"
! msgstr "(1 запись)"
!
! #: print.c:1202
  #, c-format
! msgid "(%d rows)"
! msgstr "(записей: %d)"

  #: startup.c:138
  #, c-format
--- 932,944 ----
  msgid "(No rows)\n"
  msgstr "(Нет записей)\n"

! #: print.c:2351
  #, c-format
! msgid "(%lu row)"
! msgid_plural "(%lu rows)"
! msgstr[0] "(%lu строка)"
! msgstr[1] "(%lu строки)"
! msgstr[2] "(%lu строк)"

  #: startup.c:138
  #, c-format

--
Sergey Burladyan

pgsql-hackers by date:

Previous
From: Jaime Casanova
Date:
Subject: Re: Open 8.4 item list
Next
From: James Pye
Date:
Subject: Re: xpath processing brain dead