r19192 - htdocs/trunk/externals - Update php_gettext, patch by Tao Wang

Geert Janssens gjanssens at code.gnucash.org
Thu May 20 16:23:47 EDT 2010


Author: gjanssens
Date: 2010-05-20 16:23:47 -0400 (Thu, 20 May 2010)
New Revision: 19192
Trac: http://svn.gnucash.org/trac/changeset/19192

Modified:
   htdocs/trunk/externals/gettext.inc
   htdocs/trunk/externals/gettext.php
Log:
Update php_gettext, patch by Tao Wang

Modified: htdocs/trunk/externals/gettext.inc
===================================================================
--- htdocs/trunk/externals/gettext.inc	2010-05-20 20:16:47 UTC (rev 19191)
+++ htdocs/trunk/externals/gettext.inc	2010-05-20 20:23:47 UTC (rev 19192)
@@ -62,6 +62,56 @@
 // Utility functions
 
 /**
+ * Return a list of locales to try for any POSIX-style locale specification.
+ */
+function get_list_of_locales($locale) {
+  /* Figure out all possible locale names and start with the most
+   * specific ones.  I.e. for sr_CS.UTF-8 at latin, look through all of
+   * sr_CS.UTF-8 at latin, sr_CS at latin, sr at latin, sr_CS.UTF-8, sr_CS, sr.
+   */
+  $locale_names = array();
+  $lang = NULL;
+  $country = NULL;
+  $charset = NULL;
+  $modifier = NULL;
+  if ($locale) {
+    if (preg_match("/^(?P<lang>[a-z]{2,3})"              // language code
+                   ."(?:_(?P<country>[A-Z]{2}))?"           // country code
+                   ."(?:\.(?P<charset>[-A-Za-z0-9_]+))?"    // charset
+                   ."(?:@(?P<modifier>[-A-Za-z0-9_]+))?$/",  // @ modifier
+                   $locale, $matches)) {
+
+      if (isset($matches["lang"])) $lang = $matches["lang"];
+      if (isset($matches["country"])) $country = $matches["country"];
+      if (isset($matches["charset"])) $charset = $matches["charset"];
+      if (isset($matches["modifier"])) $modifier = $matches["modifier"];
+
+      if ($modifier) {
+        if ($country) {
+          if ($charset)
+            array_push($locale_names, "${lang}_$country.$charset@$modifier");
+          array_push($locale_names, "${lang}_$country@$modifier");
+        } elseif ($charset)
+            array_push($locale_names, "${lang}.$charset@$modifier");
+        array_push($locale_names, "$lang@$modifier");
+      }
+      if ($country) {
+        if ($charset)
+          array_push($locale_names, "${lang}_$country.$charset");
+        array_push($locale_names, "${lang}_$country");
+      } elseif ($charset)
+          array_push($locale_names, "${lang}.$charset");
+      array_push($locale_names, $lang);
+    }
+
+    // If the locale name doesn't match POSIX style, just include it as-is.
+    if (!in_array($locale, $locale_names))
+      array_push($locale_names, $locale);
+  }
+  return $locale_names;
+}
+
+/**
  * Utility function to get a StreamReader for the given text domain.
  */
 function _get_reader($domain=null, $category=5, $enable_cache=true) {
@@ -73,27 +123,8 @@
         $bound_path = isset($text_domains[$domain]->path) ?
           $text_domains[$domain]->path : './';
         $subpath = $LC_CATEGORIES[$category] ."/$domain.mo";
-        /* Figure out all possible locale names and start with the most
-           specific ones.  I.e. for sr_CS.UTF-8 at latin, look through all of
-           sr_CS.UTF-8 at latin, sr_CS at latin, sr at latin, sr_CS.UTF-8, sr_CS, sr.
-        */
-        $locale_names = array();
-        if (preg_match("/([a-z]{2,3})"            // language code
-                       ."(_([A-Z]{2}))?"          // country code
-                       ."(\.([-A-Za-z0-9_]))?"    // charset
-                       ."(@([-A-Za-z0-9_]+))?/",  // @ modifier
-                       $locale, $matches)) {
-          list(,$lang,,$country,,$charset,,$modifier) = $matches;
-          if ($modifier) {
-            $locale_names = array("${lang}_$country.$charset@$modifier",
-                                  "${lang}_$country@$modifier",
-                                  "$lang@$modifier");
-          }
-          array_push($locale_names,
-                     "${lang}_$country.$charset", "${lang}_$country", "$lang");
-        }
-        array_push($locale_names, $locale);
 
+        $locale_names = get_list_of_locales($locale);
         $input = null;
         foreach ($locale_names as $locale) {
           $full_path = $bound_path . $locale . "/" . $subpath;
@@ -124,8 +155,10 @@
 /**
  * Checks if the current locale is supported on this system.
  */
-function _check_locale() {
+function _check_locale_and_function($function=false) {
     global $EMULATEGETTEXT;
+    if ($function and !function_exists($function))
+        return false;
     return !$EMULATEGETTEXT;
 }
 
@@ -153,11 +186,19 @@
 }
 
 
-
-
 // Custom implementation of the standard gettext related functions
 
 /**
+ * Returns passed in $locale, or environment variable $LANG if $locale == ''.
+ */
+function _get_default_locale($locale) {
+  if ($locale == '') // emulate variable support
+    return getenv('LANG');
+  else
+    return $locale;
+}
+
+/**
  * Sets a requested locale, if needed emulates it.
  */
 function _setlocale($category, $locale) {
@@ -170,18 +211,21 @@
             // even if we tried to read locale without setting it first
             return _setlocale($category, $CURRENTLOCALE);
     } else {
-        $ret = 0;
-        if (function_exists('setlocale')) // I don't know if this ever happens ;)
-           $ret = setlocale($category, $locale);
-        if (($ret and $locale == '') or ($ret == $locale)) {
+        if (function_exists('setlocale')) {
+          $ret = setlocale($category, $locale);
+          if (($locale == '' and !$ret) or // failed setting it by env
+              ($locale != '' and $ret != $locale)) { // failed setting it
+            // Failed setting it according to environment.
+            $CURRENTLOCALE = _get_default_locale($locale);
+            $EMULATEGETTEXT = 1;
+          } else {
+            $CURRENTLOCALE = $ret;
             $EMULATEGETTEXT = 0;
-            $CURRENTLOCALE = $ret;
+          }
         } else {
-          if ($locale == '') // emulate variable support
-             $CURRENTLOCALE = getenv('LANG');
-        else
-            $CURRENTLOCALE = $locale;
-            $EMULATEGETTEXT = 1;
+          // No function setlocale(), emulate it all.
+          $CURRENTLOCALE = _get_default_locale($locale);
+          $EMULATEGETTEXT = 1;
         }
         // Allow locale to be changed on the go for one translation domain.
         global $text_domains, $default_domain;
@@ -231,21 +275,21 @@
  */
 function _gettext($msgid) {
     $l10n = _get_reader();
-    //return $l10n->translate($msgid);
     return _encode($l10n->translate($msgid));
 }
+
 /**
  * Alias for gettext.
  */
 function __($msgid) {
     return _gettext($msgid);
 }
+
 /**
  * Plural version of gettext.
  */
 function _ngettext($single, $plural, $number) {
     $l10n = _get_reader();
-    //return $l10n->ngettext($single, $plural, $number);
     return _encode($l10n->ngettext($single, $plural, $number));
 }
 
@@ -254,15 +298,14 @@
  */
 function _dgettext($domain, $msgid) {
     $l10n = _get_reader($domain);
-    //return $l10n->translate($msgid);
     return _encode($l10n->translate($msgid));
 }
+
 /**
  * Plural version of dgettext.
  */
 function _dngettext($domain, $single, $plural, $number) {
     $l10n = _get_reader($domain);
-    //return $l10n->ngettext($single, $plural, $number);
     return _encode($l10n->ngettext($single, $plural, $number));
 }
 
@@ -271,7 +314,6 @@
  */
 function _dcgettext($domain, $msgid, $category) {
     $l10n = _get_reader($domain, $category);
-    //return $l10n->translate($msgid);
     return _encode($l10n->translate($msgid));
 }
 /**
@@ -279,63 +321,161 @@
  */
 function _dcngettext($domain, $single, $plural, $number, $category) {
     $l10n = _get_reader($domain, $category);
-    //return $l10n->ngettext($single, $plural, $number);
     return _encode($l10n->ngettext($single, $plural, $number));
 }
 
+/**
+ * Context version of gettext.
+ */
+function _pgettext($context, $msgid) {
+    $l10n = _get_reader();
+    return _encode($l10n->pgettext($context, $msgid));
+}
 
+/**
+ * Override the current domain in a context gettext call.
+ */
+function _dpgettext($domain, $context, $msgid) {
+    $l10n = _get_reader($domain);
+    return _encode($l10n->pgettext($context, $msgid));
+}
 
-// Wrappers to use if the standard gettext functions are available, but the current locale is not supported by the system.
-// Use the standard impl if the current locale is supported, use the custom impl otherwise.
+/**
+ * Overrides the domain and category for a single context-based lookup.
+ */
+function _dcpgettext($domain, $context, $msgid, $category) {
+    $l10n = _get_reader($domain, $category);
+    return _encode($l10n->pgettext($context, $msgid));
+}
 
+/**
+ * Context version of ngettext.
+ */
+function _npgettext($context, $singular, $plural) {
+    $l10n = _get_reader();
+    return _encode($l10n->npgettext($context, $singular, $plural));
+}
+
+/**
+ * Override the current domain in a context ngettext call.
+ */
+function _dnpgettext($domain, $context, $singular, $plural) {
+    $l10n = _get_reader($domain);
+    return _encode($l10n->npgettext($context, $singular, $plural));
+}
+
+/**
+ * Overrides the domain and category for a plural context-based lookup.
+ */
+function _dcnpgettext($domain, $context, $singular, $plural, $category) {
+    $l10n = _get_reader($domain, $category);
+    return _encode($l10n->npgettext($context, $singular, $plural));
+}
+
+
+
+// Wrappers to use if the standard gettext functions are available,
+// but the current locale is not supported by the system.
+// Use the standard impl if the current locale is supported, use the
+// custom impl otherwise.
+
 function T_setlocale($category, $locale) {
     return _setlocale($category, $locale);
 }
 
 function T_bindtextdomain($domain, $path) {
-    if (_check_locale()) return bindtextdomain($domain, $path);
+    if (_check_locale_and_function()) return bindtextdomain($domain, $path);
     else return _bindtextdomain($domain, $path);
 }
 function T_bind_textdomain_codeset($domain, $codeset) {
     // bind_textdomain_codeset is available only in PHP 4.2.0+
-    if (_check_locale() and function_exists('bind_textdomain_codeset')) return bind_textdomain_codeset($domain, $codeset);
+    if (_check_locale_and_function('bind_textdomain_codeset'))
+        return bind_textdomain_codeset($domain, $codeset);
     else return _bind_textdomain_codeset($domain, $codeset);
 }
 function T_textdomain($domain) {
-    if (_check_locale()) return textdomain($domain);
+    if (_check_locale_and_function()) return textdomain($domain);
     else return _textdomain($domain);
 }
 function T_gettext($msgid) {
-    if (_check_locale()) return gettext($msgid);
+    if (_check_locale_and_function()) return gettext($msgid);
     else return _gettext($msgid);
 }
 function T_($msgid) {
-    if (_check_locale()) return _($msgid);
+    if (_check_locale_and_function()) return _($msgid);
     return __($msgid);
 }
 function T_ngettext($single, $plural, $number) {
-    if (_check_locale()) return ngettext($single, $plural, $number);
+    if (_check_locale_and_function())
+        return ngettext($single, $plural, $number);
     else return _ngettext($single, $plural, $number);
 }
 function T_dgettext($domain, $msgid) {
-    if (_check_locale()) return dgettext($domain, $msgid);
+    if (_check_locale_and_function()) return dgettext($domain, $msgid);
     else return _dgettext($domain, $msgid);
 }
 function T_dngettext($domain, $single, $plural, $number) {
-    if (_check_locale()) return dngettext($domain, $single, $plural, $number);
+    if (_check_locale_and_function())
+        return dngettext($domain, $single, $plural, $number);
     else return _dngettext($domain, $single, $plural, $number);
 }
 function T_dcgettext($domain, $msgid, $category) {
-    if (_check_locale()) return dcgettext($domain, $msgid, $category);
+    if (_check_locale_and_function())
+        return dcgettext($domain, $msgid, $category);
     else return _dcgettext($domain, $msgid, $category);
 }
 function T_dcngettext($domain, $single, $plural, $number, $category) {
-    if (_check_locale()) return dcngettext($domain, $single, $plural, $number, $category);
+    if (_check_locale_and_function())
+      return dcngettext($domain, $single, $plural, $number, $category);
     else return _dcngettext($domain, $single, $plural, $number, $category);
 }
 
+function T_pgettext($context, $msgid) {
+  if (_check_locale_and_function('pgettext'))
+      return pgettext($context, $msgid);
+  else
+      return _pgettext($context, $msgid);
+}
 
+function T_dpgettext($domain, $context, $msgid) {
+  if (_check_locale_and_function('dpgettext'))
+      return dpgettext($domain, $context, $msgid);
+  else
+      return _dpgettext($domain, $context, $msgid);
+}
 
+function T_dcpgettext($domain, $context, $msgid, $category) {
+  if (_check_locale_and_function('dcpgettext'))
+      return dcpgettext($domain, $context, $msgid, $category);
+  else
+      return _dcpgettext($domain, $context, $msgid, $category);
+}
+
+function T_npgettext($context, $singular, $plural) {
+    if (_check_locale_and_function('npgettext'))
+        return npgettext($context, $single, $plural, $number);
+    else
+        return _npgettext($context, $single, $plural, $number);
+}
+
+function T_dnpgettext($domain, $context, $singular, $plural) {
+  if (_check_locale_and_function('dnpgettext'))
+      return dnpgettext($domain, $context, $single, $plural, $number);
+  else
+      return _dnpgettext($domain, $context, $single, $plural, $number);
+}
+
+function T_dcnpgettext($domain, $context, $singular, $plural, $category) {
+    if (_check_locale_and_function('dcnpgettext'))
+        return dcnpgettext($domain, $context, $single,
+                           $plural, $number, $category);
+    else
+        return _dcnpgettext($domain, $context, $single,
+                            $plural, $number, $category);
+}
+
+
+
 // Wrappers used as a drop in replacement for the standard gettext functions
 
 if (!function_exists('gettext')) {
@@ -369,6 +509,26 @@
     function dcngettext($domain, $single, $plural, $number, $category) {
         return _dcngettext($domain, $single, $plural, $number, $category);
     }
+    function pgettext($context, $msgid) {
+        return _pgettext($context, $msgid);
+    }
+    function npgettext($context, $single, $plural, $number) {
+        return _npgettext($context, $single, $plural, $number);
+    }
+    function dpgettext($domain, $context, $msgid) {
+        return _dpgettext($domain, $context, $msgid);
+    }
+    function dnpgettext($domain, $context, $single, $plural, $number) {
+        return _dnpgettext($domain, $context, $single, $plural, $number);
+    }
+    function dcpgettext($domain, $context, $msgid, $category) {
+        return _dcpgettext($domain, $context, $msgid, $category);
+    }
+    function dcnpgettext($domain, $context, $single, $plural,
+                         $number, $category) {
+      return _dcnpgettext($domain, $context, $single, $plural,
+                          $number, $category);
+    }
 }
 
 ?>

Modified: htdocs/trunk/externals/gettext.php
===================================================================
--- htdocs/trunk/externals/gettext.php	2010-05-20 20:16:47 UTC (rev 19191)
+++ htdocs/trunk/externals/gettext.php	2010-05-20 20:23:47 UTC (rev 19192)
@@ -134,7 +134,7 @@
    * Loads the translation tables from the MO file into the cache
    * If caching is enabled, also loads all strings into a cache
    * to speed up translation lookups
-   * 
+   *
    * @access private
    */
   function load_tables() {
@@ -144,10 +144,14 @@
       return;
 
     /* get original and translations tables */
-    $this->STREAM->seekto($this->originals);
-    $this->table_originals = $this->readintarray($this->total * 2);
-    $this->STREAM->seekto($this->translations);
-    $this->table_translations = $this->readintarray($this->total * 2);
+    if (!is_array($this->table_originals)) {
+      $this->STREAM->seekto($this->originals);
+      $this->table_originals = $this->readintarray($this->total * 2);
+    }
+    if (!is_array($this->table_translations)) {
+      $this->STREAM->seekto($this->translations);
+      $this->table_translations = $this->readintarray($this->total * 2);
+    }
 
     if ($this->enable_cache) {
       $this->cache_translations = array ();
@@ -301,6 +305,20 @@
   }
 
   /**
+   * Parse full PO header and extract only plural forms line.
+   *
+   * @access private
+   * @return string verbatim plural form header field
+   */
+  function extract_plural_forms_header_from_po_header($header) {
+    if (preg_match("/(^|\n)plural-forms: ([^\n]*)\n/i", $header, $regs))
+      $expr = $regs[2];
+    else
+      $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
+    return $expr;
+  }
+
+  /**
    * Get possible plural forms from MO header
    *
    * @access private
@@ -318,11 +336,7 @@
       } else {
         $header = $this->get_translation_string(0);
       }
-      if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
-        $expr = $regs[1];
-      else
-        $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
-
+      $expr = $this->extract_plural_forms_header_from_po_header($header);
       $this->pluralheader = $this->sanitize_plural_expression($expr);
     }
     return $this->pluralheader;
@@ -370,7 +384,7 @@
     $select = $this->select_string($number);
 
     // this should contains all strings separated by NULLs
-    $key = $single.chr(0).$plural;
+    $key = $single . chr(0) . $plural;
 
 
     if ($this->enable_cache) {
@@ -393,6 +407,15 @@
     }
   }
 
+  function pgettext($context, $msgid) {
+    $key = $context . chr(4) . $msgid;
+    return $this->translate($key);
+  }
+
+  function npgettext($context, $singular, $plural, $number) {
+    $singular = $context . chr(4) . $singular;
+    return $this->ngettext($singular, $plural, $number);
+  }
 }
 
 ?>



More information about the gnucash-changes mailing list