diff --git a/include/php-gettext-1.0.7/ChangeLog b/include/php-gettext-1.0.7/ChangeLog deleted file mode 100644 index 5e0949df..00000000 --- a/include/php-gettext-1.0.7/ChangeLog +++ /dev/null @@ -1,144 +0,0 @@ -2006-02-07 Danilo Šegan - - * examples/pigs_dropin.php: comment-out bind_textdomain_codeset - - * gettext.inc (T_bind_textdomain_codeset): bind_textdomain_codeset - is available only in PHP 4.2.0+ (thanks to Jens A. Tkotz). - - * Makefile: Include gettext.inc in DIST_FILES, VERSION up to - 1.0.7. - -2006-02-03 Danilo Šegan - - Added setlocale() emulation as well. - - * examples/pigs_dropin.php: Use T_setlocale() and locale_emulation(). - * examples/pigs_fallback.php: Use T_setlocale() and locale_emulation(). - - * gettext.inc: Added globals $EMULATEGETTEXT and $CURRENTLOCALE. - (locale_emulation): Whether emulation is active. - (_check_locale): Rewrite. - (_setlocale): Added emulated setlocale function. - (T_setlocale): Wrapper around _setlocale. - (_get_reader): Use variables and _setlocale. - -2006-02-02 Danilo Šegan - - Fix bug #12192. - - * examples/locale/sr_CS/LC_MESSAGES/messages.po: Correct grammar. - * examples/locale/sr_CS/LC_MESSAGES/messages.mo: Rebuild. - -2006-02-02 Danilo Šegan - - Fix bug #15419. - - * streams.php: Support for PHP 5.1.1 fread() which reads most 8kb. - (Fix by Piotr Szotkowski ) - -2006-02-02 Danilo Šegan - - Merge Steven Armstrong's changes, supporting standard gettext - interfaces: - - * examples/*: Restructured examples. - * gettext.inc: Added. - * AUTHORS: Added Steven. - * Makefile (VERSION): Up to 1.0.6. - -2006-01-28 Nico Kaiser - - * gettext.php (select_string): Fix "true" <-> 1 difference of PHP - -2005-07-29 Danilo Šegan - - * Makefile (VERSION): Up to 1.0.5. - -2005-07-29 Danilo Šegan - - Fixes bug #13850. - - * gettext.php (gettext_reader): check $Reader->error as well. - -2005-07-29 Danilo Šegan - - * Makefile (VERSION): Up to 1.0.4. - -2005-07-29 Danilo Šegan - - Fixes bug #13771. - - * gettext.php (gettext_reader->get_plural_forms): Plural forms - header extraction regex change. Reported by Edgar Gonzales. - -2005-02-28 Danilo Šegan - - * AUTHORS: Added Nico to the list. - - * Makefile (VERSION): Up to 1.0.3. - - * README: Updated. - -2005-02-28 Danilo Šegan - - * gettext.php: Added pre-loading, code documentation, and many - code clean-ups by Nico Kaiser . - -2005-02-28 Danilo Šegan - - * streams.php (FileReader.read): Handle read($bytes = 0). - - * examples/pigs.php: Prefix gettext function names with T or T_. - - * examples/update: Use the same keywords T_ and T_ngettext. - - * streams.php: Added CachedFileReader. - -2003-11-11 Danilo Šegan - - * gettext.php: Added hashing to find_string. - -2003-11-01 Danilo Šegan - - * Makefile (DIST_FILES): Replaced LICENSE with COPYING. - (VERSION): Up to 1.0.2. - - * AUTHORS: Minor edits. - - * README: Minor edits. - - * COPYING: Removed LICENSE, added this file. - - * gettext.php: Added copyright notice and disclaimer. - * streams.php: Same. - * examples/pigs.php: Same. - -2003-10-23 Danilo Šegan - - * Makefile: Upped version to 1.0.1. - - * gettext.php (gettext_reader): Remove a call to set_total_plurals. - (set_total_plurals): Removed unused function for some better days. - -2003-10-23 Danilo Šegan - - * Makefile: Added, version 1.0.0. - - * examples/*: Added an example of usage. - - * README: Described all the crap. - -2003-10-22 Danilo Šegan - - * gettext.php: Plural forms implemented too. - - * streams.php: Added FileReader for direct access to files (no - need to keep file in memory). - - * gettext.php: It works, except for plural forms. - - * streams.php: Created abstract class StreamReader. - Added StringReader class. - - * gettext.php: Started writing gettext_reader. - diff --git a/include/php-gettext-1.0.7/gettext.inc b/include/php-gettext-1.0.7/gettext.inc deleted file mode 100644 index 740984ce..00000000 --- a/include/php-gettext-1.0.7/gettext.inc +++ /dev/null @@ -1,320 +0,0 @@ - - - Drop in replacement for native gettext. - - This file is part of PHP-gettext. - - PHP-gettext 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 2 of the License, or - (at your option) any later version. - - PHP-gettext 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 PHP-gettext; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -/* -LC_CTYPE 0 -LC_NUMERIC 1 -LC_TIME 2 -LC_COLLATE 3 -LC_MONETARY 4 -LC_MESSAGES 5 -LC_ALL 6 -*/ - -if (!defined('LC_MESSAGES')) define('LC_MESSAGES', 5); - -require('streams.php'); -require('gettext.php'); - - -// Variables - -global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE; -$text_domains = array(); -$default_domain = 'messages'; -$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL'); -$EMULATEGETTEXT = 0; -$CURRENTLOCALE = ''; - - -// Utility functions - -/** - * Utility function to get a StreamReader for the given text domain. - */ -function _get_reader($domain=null, $category=5, $enable_cache=true) { - global $text_domains, $default_domain, $LC_CATEGORIES; - if (!isset($domain)) $domain = $default_domain; - if (!isset($text_domains[$domain]->l10n)) { - // get the current locale - $locale = _setlocale(LC_MESSAGES, 0); - $p = isset($text_domains[$domain]->path) ? $text_domains[$domain]->path : './'; - $path = $p . "$locale/". $LC_CATEGORIES[$category] ."/$domain.mo"; - if (file_exists($path)) { - $input = new FileReader($path); - } - else { - $input = null; - } - $text_domains[$domain]->l10n = new gettext_reader($input, $enable_cache); - } - return $text_domains[$domain]->l10n; -} - -/** - * Returns whether we are using our emulated gettext API or PHP built-in one. - */ -function locale_emulation() { - global $EMULATEGETTEXT; - return $EMULATEGETTEXT; -} - -/** - * Checks if the current locale is supported on this system. - */ -function _check_locale() { - global $EMULATEGETTEXT; - return !$EMULATEGETTEXT; -} - -/** - * Get the codeset for the given domain. - */ -function _get_codeset($domain=null) { - global $text_domains, $default_domain, $LC_CATEGORIES; - if (!isset($domain)) $domain = $default_domain; - return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding'); -} - -/** - * Convert the given string to the encoding set by bind_textdomain_codeset. - */ -function _encode($text) { - $source_encoding = mb_detect_encoding($text); - $target_encoding = _get_codeset(); - if ($source_encoding != $target_encoding) { - return mb_convert_encoding($text, $target_encoding, $source_encoding); - } - else { - return $text; - } -} - - - - -// Custom implementation of the standard gettext related functions - -/** - * Sets a requested locale, if needed emulates it. - */ -function _setlocale($category, $locale) { - global $CURRENTLOCALE, $EMULATEGETTEXT; - if ($locale === 0) { // use === to differentiate between string "0" - if ($CURRENTLOCALE != '') - return $CURRENTLOCALE; - else - // obey LANG variable, maybe extend to support all of LC_* vars - // 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)) { - $EMULATEGETTEXT = 0; - $CURRENTLOCALE = $ret; - } else { - if ($locale == '') // emulate variable support - $CURRENTLOCALE = getenv('LANG'); - else - $CURRENTLOCALE = $locale; - $EMULATEGETTEXT = 1; - } - return $CURRENTLOCALE; - } -} - -/** - * Sets the path for a domain. - */ -function _bindtextdomain($domain, $path) { - global $text_domains; - // ensure $path ends with a slash - if ($path[strlen($path) - 1] != '/') $path .= '/'; - elseif ($path[strlen($path) - 1] != '\\') $path .= '\\'; - $text_domains[$domain]->path = $path; -} - -/** - * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. - */ -function _bind_textdomain_codeset($domain, $codeset) { - global $text_domains; - $text_domains[$domain]->codeset = $codeset; -} - -/** - * Sets the default domain. - */ -function _textdomain($domain) { - global $default_domain; - $default_domain = $domain; -} - -/** - * Lookup a message in the current domain. - */ -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)); -} - -/** - * Override the current domain. - */ -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)); -} - -/** - * Overrides the domain and category for a single lookup. - */ -function _dcgettext($domain, $msgid, $category) { - $l10n = _get_reader($domain, $category); - //return $l10n->translate($msgid); - return _encode($l10n->translate($msgid)); -} -/** - * Plural version of dcgettext. - */ -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)); -} - - - -// 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); - 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); - else return _bind_textdomain_codeset($domain, $codeset); -} -function T_textdomain($domain) { - if (_check_locale()) return textdomain($domain); - else return _textdomain($domain); -} -function T_gettext($msgid) { - if (_check_locale()) return gettext($msgid); - else return _gettext($msgid); -} -function T_($msgid) { - if (_check_locale()) return _($msgid); - return __($msgid); -} -function T_ngettext($single, $plural, $number) { - if (_check_locale()) return ngettext($single, $plural, $number); - else return _ngettext($single, $plural, $number); -} -function T_dgettext($domain, $msgid) { - if (_check_locale()) 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); - else return _dngettext($domain, $single, $plural, $number); -} -function T_dcgettext($domain, $msgid, $category) { - if (_check_locale()) 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); - else return _dcngettext($domain, $single, $plural, $number, $category); -} - - - -// Wrappers used as a drop in replacement for the standard gettext functions - -if (!function_exists('gettext')) { - function bindtextdomain($domain, $path) { - return _bindtextdomain($domain, $path); - } - function bind_textdomain_codeset($domain, $codeset) { - return _bind_textdomain_codeset($domain, $codeset); - } - function textdomain($domain) { - return _textdomain($domain); - } - function gettext($msgid) { - return _gettext($msgid); - } - function _($msgid) { - return __($msgid); - } - function ngettext($single, $plural, $number) { - return _ngettext($single, $plural, $number); - } - function dgettext($domain, $msgid) { - return _dgettext($domain, $msgid); - } - function dngettext($domain, $single, $plural, $number) { - return _dngettext($domain, $single, $plural, $number); - } - function dcgettext($domain, $msgid, $category) { - return _dcgettext($domain, $msgid, $category); - } - function dcngettext($domain, $single, $plural, $number, $category) { - return _dcngettext($domain, $single, $plural, $number, $category); - } -} - -?> diff --git a/include/php-gettext-1.0.7/AUTHORS b/include/php-gettext-1.0.9/AUTHORS similarity index 100% rename from include/php-gettext-1.0.7/AUTHORS rename to include/php-gettext-1.0.9/AUTHORS diff --git a/include/php-gettext-1.0.7/COPYING b/include/php-gettext-1.0.9/COPYING similarity index 100% rename from include/php-gettext-1.0.7/COPYING rename to include/php-gettext-1.0.9/COPYING diff --git a/include/php-gettext-1.0.7/Makefile b/include/php-gettext-1.0.9/Makefile similarity index 93% rename from include/php-gettext-1.0.7/Makefile rename to include/php-gettext-1.0.9/Makefile index 2dba9115..f0b5bf99 100644 --- a/include/php-gettext-1.0.7/Makefile +++ b/include/php-gettext-1.0.9/Makefile @@ -1,12 +1,11 @@ PACKAGE = php-gettext-$(VERSION) -VERSION = 1.0.7 +VERSION = 1.0.9 DIST_FILES = \ gettext.php \ gettext.inc \ streams.php \ AUTHORS \ - ChangeLog \ README \ COPYING \ Makefile \ @@ -30,3 +29,5 @@ dist: rm -rf $(PACKAGE); \ fi; +clean: + rm -f $(PACKAGE).tar.gz diff --git a/include/php-gettext-1.0.7/README b/include/php-gettext-1.0.9/README similarity index 74% rename from include/php-gettext-1.0.7/README rename to include/php-gettext-1.0.9/README index c7525e29..bca4f916 100644 --- a/include/php-gettext-1.0.7/README +++ b/include/php-gettext-1.0.9/README @@ -1,9 +1,9 @@ -PHP-gettext 1.0 +PHP-gettext 1.0 (https://launchpad.net/php-gettext) -Copyright 2003, 2006 -- Danilo "angry with PHP[1]" Segan +Copyright 2003, 2006, 2009 -- Danilo "angry with PHP[1]" Segan Licensed under GPLv2 (or any later version, see COPYING) -[1] PHP is actually cyrillic, and translates roughly to +[1] PHP is actually cyrillic, and translates roughly to "works-doesn't-work" (UTF-8: Ради-Не-Ради) @@ -50,36 +50,16 @@ Features file data, I used imaginary abstract class StreamReader to do all the input (check streams.php). For your convenience, I've already provided two classes for reading files: FileReader and - StringReader (CachedFileReader is a combination of the two: it - loads entire file contents into a string, and then works on that). - See example below for usage. You can for instance use StringReader - when you read in data from a database, or you can create your own - derivative of StreamReader for anything you like. - + StringReader (CachedFileReader is a combination of the two: it + loads entire file contents into a string, and then works on that). + See example below for usage. You can for instance use StringReader + when you read in data from a database, or you can create your own + derivative of StreamReader for anything you like. + Bugs - Plural-forms field in MO header (translation for empty string, - i.e. "") is treated according to PHP syntactic rules (it's - eval()ed). Since these should actually follow C syntax, there are - some problems. - - For instance, I'm used to using this: - 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; - but it fails with PHP (it sets $plural=2 instead of 0 for $n==1). - - The fix is usually simple, but I'm lazy to go into the details of - PHP operator precedence, and maybe try to fix it. In here, I had - to put everything after the first ':' in parenthesis: - 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); - That works, and I'm satisfied. - - Besides this one, there are probably a bunch of other bugs, since - I hate PHP (did I mention it already? no? strange), and don't - know it very well. So, feel free to fix any of those and report - them back to me at . + Report them on https://bugs.launchpad.net/php-gettext Usage @@ -94,19 +74,19 @@ Usage Then, use that as a parameter to gettext_reader constructor: $wohoo = new gettext_reader($streamer); - If you want to disable pre-loading of entire message catalog in - memory (if, for example, you have a multi-thousand message catalog - which you'll use only occasionally), use "false" for second + If you want to disable pre-loading of entire message catalog in + memory (if, for example, you have a multi-thousand message catalog + which you'll use only occasionally), use "false" for second parameter to gettext_reader constructor: $wohoo = new gettext_reader($streamer, false); From now on, you have all the benefits of gettext data at your - disposal, so may run: + disposal, so may run: print $wohoo->translate("This is a test"); print $wohoo->ngettext("%d bird", "%d birds", $birds); You might need to pass parameter "-k" to xgettext to make it - extract all the strings. In above example, try with + extract all the strings. In above example, try with xgettext -ktranslate -kngettext:1,2 file.php what should create messages.po which contains two messages for translation. @@ -118,8 +98,8 @@ Usage Usage with gettext.inc (standard gettext interfaces emulation) - Check example in examples/pig_dropin.php, basically you include - gettext.inc and use all the standard gettext interfaces as + Check example in examples/pig_dropin.php, basically you include + gettext.inc and use all the standard gettext interfaces as documented on: http://www.php.net/gettext @@ -137,20 +117,12 @@ Example There is also simple "update" script that can be used to generate POT file and to update the translation using msgmerge. -Interesting TODO: +TODO: - o Try to parse "plural-forms" header field, and to follow C syntax - rules. This won't be easy. + o Improve speed to be even more comparable to the native gettext + implementation. -Boring TODO: - - o Learn PHP and fix bugs, slowness and other stuff resulting from - my lack of knowledge (but *maybe*, it's not my knowledge that is - bad, but PHP itself ;-). - - (This is mostly done thanks to Nico Kaiser.) - - o Try to use hash tables in MO files: with pre-loading, would it + o Try to use hash tables in MO files: with pre-loading, would it be useful at all? Never-asked-questions: @@ -160,7 +132,7 @@ Never-asked-questions: Well, it's quite simple. I consider that the first released thing should be labeled "version 1" (first, right?). Zero is there to - indicate that there's zero improvement and/or change compared to + indicate that there's zero improvement and/or change compared to "version 1". I plan to use version numbers 1.0.* for small bugfixes, and to @@ -173,7 +145,7 @@ Never-asked-questions: Mozart's 40th Symphony (there is one like that, right?). o Can I...? - + Yes, you can. This is free software (as in freedom, free speech), and you might do whatever you wish with it, provided you do not limit freedom of others (GPL). diff --git a/include/php-gettext-1.0.7/examples/index.php b/include/php-gettext-1.0.9/examples/index.php similarity index 100% rename from include/php-gettext-1.0.7/examples/index.php rename to include/php-gettext-1.0.9/examples/index.php diff --git a/include/php-gettext-1.0.7/examples/locale/de_CH/LC_MESSAGES/messages.mo b/include/php-gettext-1.0.9/examples/locale/de_CH/LC_MESSAGES/messages.mo similarity index 100% rename from include/php-gettext-1.0.7/examples/locale/de_CH/LC_MESSAGES/messages.mo rename to include/php-gettext-1.0.9/examples/locale/de_CH/LC_MESSAGES/messages.mo diff --git a/include/php-gettext-1.0.7/examples/locale/de_CH/LC_MESSAGES/messages.po b/include/php-gettext-1.0.9/examples/locale/de_CH/LC_MESSAGES/messages.po similarity index 100% rename from include/php-gettext-1.0.7/examples/locale/de_CH/LC_MESSAGES/messages.po rename to include/php-gettext-1.0.9/examples/locale/de_CH/LC_MESSAGES/messages.po diff --git a/include/php-gettext-1.0.7/examples/locale/sr_CS/LC_MESSAGES/messages.mo b/include/php-gettext-1.0.9/examples/locale/sr_CS/LC_MESSAGES/messages.mo similarity index 70% rename from include/php-gettext-1.0.7/examples/locale/sr_CS/LC_MESSAGES/messages.mo rename to include/php-gettext-1.0.9/examples/locale/sr_CS/LC_MESSAGES/messages.mo index 6ffccfd5..497c8830 100644 Binary files a/include/php-gettext-1.0.7/examples/locale/sr_CS/LC_MESSAGES/messages.mo and b/include/php-gettext-1.0.9/examples/locale/sr_CS/LC_MESSAGES/messages.mo differ diff --git a/include/php-gettext-1.0.7/examples/locale/sr_CS/LC_MESSAGES/messages.po b/include/php-gettext-1.0.9/examples/locale/sr_CS/LC_MESSAGES/messages.po similarity index 87% rename from include/php-gettext-1.0.7/examples/locale/sr_CS/LC_MESSAGES/messages.po rename to include/php-gettext-1.0.9/examples/locale/sr_CS/LC_MESSAGES/messages.po index 7e620cc4..e5da0e94 100644 --- a/include/php-gettext-1.0.7/examples/locale/sr_CS/LC_MESSAGES/messages.po +++ b/include/php-gettext-1.0.9/examples/locale/sr_CS/LC_MESSAGES/messages.po @@ -12,7 +12,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" +"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" #: pigs.php:19 msgid "" diff --git a/include/php-gettext-1.0.7/examples/pigs_dropin.php b/include/php-gettext-1.0.9/examples/pigs_dropin.php similarity index 91% rename from include/php-gettext-1.0.7/examples/pigs_dropin.php rename to include/php-gettext-1.0.9/examples/pigs_dropin.php index edd2b0db..320a2a58 100644 --- a/include/php-gettext-1.0.7/examples/pigs_dropin.php +++ b/include/php-gettext-1.0.9/examples/pigs_dropin.php @@ -1,6 +1,6 @@ . + Copyright (c) 2003,2004,2005,2009 Danilo Segan . Copyright (c) 2005,2006 Steven Armstrong This file is part of PHP-gettext. @@ -21,10 +21,12 @@ */ +error_reporting(E_STRICT); + // define constants -define(PROJECT_DIR, realpath('./')); -define(LOCALE_DIR, PROJECT_DIR .'/locale'); -define(DEFAULT_LOCALE, 'en_US'); +define('PROJECT_DIR', realpath('./')); +define('LOCALE_DIR', PROJECT_DIR .'/locale'); +define('DEFAULT_LOCALE', 'en_US'); require_once('../gettext.inc'); diff --git a/include/php-gettext-1.0.7/examples/pigs_fallback.php b/include/php-gettext-1.0.9/examples/pigs_fallback.php similarity index 91% rename from include/php-gettext-1.0.7/examples/pigs_fallback.php rename to include/php-gettext-1.0.9/examples/pigs_fallback.php index b50f752f..5d154b6c 100644 --- a/include/php-gettext-1.0.7/examples/pigs_fallback.php +++ b/include/php-gettext-1.0.9/examples/pigs_fallback.php @@ -1,6 +1,6 @@ . + Copyright (c) 2003,2004,2005,2009 Danilo Segan . Copyright (c) 2005,2006 Steven Armstrong This file is part of PHP-gettext. @@ -21,10 +21,12 @@ */ +error_reporting(E_STRICT); + // define constants -define(PROJECT_DIR, realpath('./')); -define(LOCALE_DIR, PROJECT_DIR .'/locale'); -define(DEFAULT_LOCALE, 'en_US'); +define('PROJECT_DIR', realpath('./')); +define('LOCALE_DIR', PROJECT_DIR .'/locale'); +define('DEFAULT_LOCALE', 'en_US'); require_once('../gettext.inc'); diff --git a/include/php-gettext-1.0.7/examples/update b/include/php-gettext-1.0.9/examples/update old mode 100644 new mode 100755 similarity index 91% rename from include/php-gettext-1.0.7/examples/update rename to include/php-gettext-1.0.9/examples/update index 4819b8d0..76b4308a --- a/include/php-gettext-1.0.7/examples/update +++ b/include/php-gettext-1.0.9/examples/update @@ -1,7 +1,7 @@ #!/bin/sh TEMPLATE=pigs.pot xgettext -kT_ngettext:1,2 -kT_ -L PHP -o $TEMPLATE pigs_dropin.php -if [ x$1 == 'x-p' ]; then +if [ "x$1" = "x-p" ]; then msgfmt --statistics $TEMPLATE else if [ -f $1.po ]; then diff --git a/include/php-gettext-1.0.9/gettext.inc b/include/php-gettext-1.0.9/gettext.inc new file mode 100644 index 00000000..0911a05a --- /dev/null +++ b/include/php-gettext-1.0.9/gettext.inc @@ -0,0 +1,374 @@ + + Copyright (c) 2009 Danilo Segan + + Drop in replacement for native gettext. + + This file is part of PHP-gettext. + + PHP-gettext 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 2 of the License, or + (at your option) any later version. + + PHP-gettext 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 PHP-gettext; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +/* +LC_CTYPE 0 +LC_NUMERIC 1 +LC_TIME 2 +LC_COLLATE 3 +LC_MONETARY 4 +LC_MESSAGES 5 +LC_ALL 6 +*/ + + +// LC_MESSAGES is not available if php-gettext is not loaded +// while the other constants are already available from session extension. +if (!defined('LC_MESSAGES')) { + define('LC_MESSAGES', 5); +} + +require('streams.php'); +require('gettext.php'); + + +// Variables + +global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE; +$text_domains = array(); +$default_domain = 'messages'; +$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL'); +$EMULATEGETTEXT = 0; +$CURRENTLOCALE = ''; + +/* Class to hold a single domain included in $text_domains. */ +class domain { + var $l10n; + var $path; + var $codeset; +} + +// Utility functions + +/** + * Utility function to get a StreamReader for the given text domain. + */ +function _get_reader($domain=null, $category=5, $enable_cache=true) { + global $text_domains, $default_domain, $LC_CATEGORIES; + if (!isset($domain)) $domain = $default_domain; + if (!isset($text_domains[$domain]->l10n)) { + // get the current locale + $locale = _setlocale(LC_MESSAGES, 0); + $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@latin, look through all of + sr_CS.UTF-8@latin, sr_CS@latin, sr@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); + + $input = null; + foreach ($locale_names as $locale) { + $full_path = $bound_path . $locale . "/" . $subpath; + if (file_exists($full_path)) { + $input = new FileReader($full_path); + break; + } + } + + if (!array_key_exists($domain, $text_domains)) { + // Initialize an empty domain object. + $text_domains[$domain] = new domain(); + } + $text_domains[$domain]->l10n = new gettext_reader($input, + $enable_cache); + } + return $text_domains[$domain]->l10n; +} + +/** + * Returns whether we are using our emulated gettext API or PHP built-in one. + */ +function locale_emulation() { + global $EMULATEGETTEXT; + return $EMULATEGETTEXT; +} + +/** + * Checks if the current locale is supported on this system. + */ +function _check_locale() { + global $EMULATEGETTEXT; + return !$EMULATEGETTEXT; +} + +/** + * Get the codeset for the given domain. + */ +function _get_codeset($domain=null) { + global $text_domains, $default_domain, $LC_CATEGORIES; + if (!isset($domain)) $domain = $default_domain; + return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding'); +} + +/** + * Convert the given string to the encoding set by bind_textdomain_codeset. + */ +function _encode($text) { + $source_encoding = mb_detect_encoding($text); + $target_encoding = _get_codeset(); + if ($source_encoding != $target_encoding) { + return mb_convert_encoding($text, $target_encoding, $source_encoding); + } + else { + return $text; + } +} + + + + +// Custom implementation of the standard gettext related functions + +/** + * Sets a requested locale, if needed emulates it. + */ +function _setlocale($category, $locale) { + global $CURRENTLOCALE, $EMULATEGETTEXT; + if ($locale === 0) { // use === to differentiate between string "0" + if ($CURRENTLOCALE != '') + return $CURRENTLOCALE; + else + // obey LANG variable, maybe extend to support all of LC_* vars + // 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)) { + $EMULATEGETTEXT = 0; + $CURRENTLOCALE = $ret; + } else { + if ($locale == '') // emulate variable support + $CURRENTLOCALE = getenv('LANG'); + else + $CURRENTLOCALE = $locale; + $EMULATEGETTEXT = 1; + } + // Allow locale to be changed on the go for one translation domain. + global $text_domains, $default_domain; + unset($text_domains[$default_domain]->l10n); + return $CURRENTLOCALE; + } +} + +/** + * Sets the path for a domain. + */ +function _bindtextdomain($domain, $path) { + global $text_domains; + // ensure $path ends with a slash ('/' should work for both, but lets still play nice) + if (substr(php_uname(), 0, 7) == "Windows") { + if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/') + $path .= '\\'; + } else { + if ($path[strlen($path)-1] != '/') + $path .= '/'; + } + if (!array_key_exists($domain, $text_domains)) { + // Initialize an empty domain object. + $text_domains[$domain] = new domain(); + } + $text_domains[$domain]->path = $path; +} + +/** + * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. + */ +function _bind_textdomain_codeset($domain, $codeset) { + global $text_domains; + $text_domains[$domain]->codeset = $codeset; +} + +/** + * Sets the default domain. + */ +function _textdomain($domain) { + global $default_domain; + $default_domain = $domain; +} + +/** + * Lookup a message in the current domain. + */ +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)); +} + +/** + * Override the current domain. + */ +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)); +} + +/** + * Overrides the domain and category for a single lookup. + */ +function _dcgettext($domain, $msgid, $category) { + $l10n = _get_reader($domain, $category); + //return $l10n->translate($msgid); + return _encode($l10n->translate($msgid)); +} +/** + * Plural version of dcgettext. + */ +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)); +} + + + +// 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); + 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); + else return _bind_textdomain_codeset($domain, $codeset); +} +function T_textdomain($domain) { + if (_check_locale()) return textdomain($domain); + else return _textdomain($domain); +} +function T_gettext($msgid) { + if (_check_locale()) return gettext($msgid); + else return _gettext($msgid); +} +function T_($msgid) { + if (_check_locale()) return _($msgid); + return __($msgid); +} +function T_ngettext($single, $plural, $number) { + if (_check_locale()) return ngettext($single, $plural, $number); + else return _ngettext($single, $plural, $number); +} +function T_dgettext($domain, $msgid) { + if (_check_locale()) 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); + else return _dngettext($domain, $single, $plural, $number); +} +function T_dcgettext($domain, $msgid, $category) { + if (_check_locale()) 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); + else return _dcngettext($domain, $single, $plural, $number, $category); +} + + + +// Wrappers used as a drop in replacement for the standard gettext functions + +if (!function_exists('gettext')) { + function bindtextdomain($domain, $path) { + return _bindtextdomain($domain, $path); + } + function bind_textdomain_codeset($domain, $codeset) { + return _bind_textdomain_codeset($domain, $codeset); + } + function textdomain($domain) { + return _textdomain($domain); + } + function gettext($msgid) { + return _gettext($msgid); + } + function _($msgid) { + return __($msgid); + } + function ngettext($single, $plural, $number) { + return _ngettext($single, $plural, $number); + } + function dgettext($domain, $msgid) { + return _dgettext($domain, $msgid); + } + function dngettext($domain, $single, $plural, $number) { + return _dngettext($domain, $single, $plural, $number); + } + function dcgettext($domain, $msgid, $category) { + return _dcgettext($domain, $msgid, $category); + } + function dcngettext($domain, $single, $plural, $number, $category) { + return _dcngettext($domain, $single, $plural, $number, $category); + } +} + +?> diff --git a/include/php-gettext-1.0.7/gettext.php b/include/php-gettext-1.0.9/gettext.php old mode 100644 new mode 100755 similarity index 87% rename from include/php-gettext-1.0.7/gettext.php rename to include/php-gettext-1.0.9/gettext.php index ad94a987..8865d781 --- a/include/php-gettext-1.0.7/gettext.php +++ b/include/php-gettext-1.0.9/gettext.php @@ -1,8 +1,8 @@ . + Copyright (c) 2003, 2009 Danilo Segan . Copyright (c) 2005 Nico Kaiser - + This file is part of PHP-gettext. PHP-gettext is free software; you can redistribute it and/or modify @@ -20,13 +20,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + /** * Provides a simple gettext replacement that works independently from * the system's gettext abilities. * It can read MO files and use them for translating strings. * The files are passed to gettext_reader as a Stream (see streams.php) - * + * * This version has the ability to cache all strings and translations to * speed up the string lookup. * While the cache is enabled by default, it can be switched off with the @@ -36,7 +36,7 @@ class gettext_reader { //public: var $error = 0; // public variable that holds error code (0 if no error) - + //private: var $BYTEORDER = 0; // 0: low endian, 1: big endian var $STREAM = NULL; @@ -52,27 +52,33 @@ class gettext_reader { /* Methods */ - - + + /** * Reads a 32bit Integer from the Stream - * + * * @access private * @return Integer from the Stream */ function readint() { if ($this->BYTEORDER == 0) { // low endian - return array_shift(unpack('V', $this->STREAM->read(4))); + $input=unpack('V', $this->STREAM->read(4)); + return array_shift($input); } else { // big endian - return array_shift(unpack('N', $this->STREAM->read(4))); + $input=unpack('N', $this->STREAM->read(4)); + return array_shift($input); } } + function read($bytes) { + return $this->STREAM->read($bytes); + } + /** * Reads an array of Integers from the Stream - * + * * @param int count How many elements should be read * @return Array of Integers */ @@ -85,10 +91,10 @@ class gettext_reader { return unpack('N'.$count, $this->STREAM->read(4 * $count)); } } - + /** * Constructor - * + * * @param object Reader the StreamReader object * @param boolean enable_cache Enable or disable caching of strings (default on) */ @@ -98,34 +104,32 @@ class gettext_reader { $this->short_circuit = true; return; } - + // Caching can be turned off $this->enable_cache = $enable_cache; - // $MAGIC1 = (int)0x950412de; //bug in PHP 5 - $MAGIC1 = (int) - 1794895138; - // $MAGIC2 = (int)0xde120495; //bug - $MAGIC2 = (int) - 569244523; + $MAGIC1 = "\x95\x04\x12\xde"; + $MAGIC2 = "\xde\x12\x04\x95"; $this->STREAM = $Reader; - $magic = $this->readint(); + $magic = $this->read(4); if ($magic == $MAGIC1) { - $this->BYTEORDER = 0; - } elseif ($magic == $MAGIC2) { $this->BYTEORDER = 1; + } elseif ($magic == $MAGIC2) { + $this->BYTEORDER = 0; } else { $this->error = 1; // not MO file return false; } - + // FIXME: Do we care about revision? We should. $revision = $this->readint(); - + $this->total = $this->readint(); $this->originals = $this->readint(); $this->translations = $this->readint(); } - + /** * Loads the translation tables from the MO file into the cache * If caching is enabled, also loads all strings into a cache @@ -138,13 +142,13 @@ class gettext_reader { is_array($this->table_originals) && is_array($this->table_translations)) 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 ($this->enable_cache) { $this->cache_translations = array (); /* read all strings in the cache */ @@ -157,10 +161,10 @@ class gettext_reader { } } } - + /** * Returns a string from the "originals" table - * + * * @access private * @param int num Offset number of original string * @return string Requested string if found, otherwise '' @@ -174,10 +178,10 @@ class gettext_reader { $data = $this->STREAM->read($length); return (string)$data; } - + /** * Returns a string from the "translations" table - * + * * @access private * @param int num Offset number of original string * @return string Requested string if found, otherwise '' @@ -191,10 +195,10 @@ class gettext_reader { $data = $this->STREAM->read($length); return (string)$data; } - + /** * Binary search for string - * + * * @access private * @param string string * @param int start (internally used in recursive function) @@ -232,10 +236,10 @@ class gettext_reader { return $this->find_string($string, $half, $end); } } - + /** * Translates a string - * + * * @access public * @param string string to be translated * @return string translated string (or original, if not found) @@ -243,8 +247,8 @@ class gettext_reader { function translate($string) { if ($this->short_circuit) return $string; - $this->load_tables(); - + $this->load_tables(); + if ($this->enable_cache) { // Caching enabled, get translated string from cache if (array_key_exists($string, $this->cache_translations)) @@ -261,17 +265,52 @@ class gettext_reader { } } + /** + * Sanitize plural form expression for use in PHP eval call. + * + * @access private + * @return string sanitized plural form expression + */ + function sanitize_plural_expression($expr) { + // Get rid of disallowed characters. + $expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr); + + // Add parenthesis for tertiary '?' operator. + $expr .= ';'; + $res = ''; + $p = 0; + for ($i = 0; $i < strlen($expr); $i++) { + $ch = $expr[$i]; + switch ($ch) { + case '?': + $res .= ' ? ('; + $p++; + break; + case ':': + $res .= ') : ('; + break; + case ';': + $res .= str_repeat( ')', $p) . ';'; + $p = 0; + break; + default: + $res .= $ch; + } + } + return $res; + } + /** * Get possible plural forms from MO header - * + * * @access private * @return string plural form header */ function get_plural_forms() { - // lets assume message number 0 is header + // lets assume message number 0 is header // this is true, right? $this->load_tables(); - + // cache header field for plural forms if (! is_string($this->pluralheader)) { if ($this->enable_cache) { @@ -283,14 +322,15 @@ class gettext_reader { $expr = $regs[1]; else $expr = "nplurals=2; plural=n == 1 ? 0 : 1;"; - $this->pluralheader = $expr; + + $this->pluralheader = $this->sanitize_plural_expression($expr); } return $this->pluralheader; } /** * Detects which plural form to take - * + * * @access private * @param n count * @return int array index of the right plural form @@ -300,7 +340,7 @@ class gettext_reader { $string = str_replace('nplurals',"\$total",$string); $string = str_replace("n",$n,$string); $string = str_replace('plural',"\$plural",$string); - + $total = 0; $plural = 0; @@ -311,7 +351,7 @@ class gettext_reader { /** * Plural version of gettext - * + * * @access public * @param string single * @param string plural @@ -327,12 +367,12 @@ class gettext_reader { } // find out the appropriate form - $select = $this->select_string($number); - + $select = $this->select_string($number); + // this should contains all strings separated by NULLs $key = $single.chr(0).$plural; - - + + if ($this->enable_cache) { if (! array_key_exists($key, $this->cache_translations)) { return ($number != 1) ? $plural : $single; diff --git a/include/php-gettext-1.0.7/streams.php b/include/php-gettext-1.0.9/streams.php old mode 100644 new mode 100755 similarity index 89% rename from include/php-gettext-1.0.7/streams.php rename to include/php-gettext-1.0.9/streams.php index 50ef0ce5..3cdc1584 --- a/include/php-gettext-1.0.7/streams.php +++ b/include/php-gettext-1.0.9/streams.php @@ -1,6 +1,6 @@ . + Copyright (c) 2003, 2005, 2006, 2009 Danilo Segan . This file is part of PHP-gettext. @@ -21,29 +21,29 @@ */ -// Simple class to wrap file streams, string streams, etc. -// seek is essential, and it should be byte stream + // Simple class to wrap file streams, string streams, etc. + // seek is essential, and it should be byte stream class StreamReader { // should return a string [FIXME: perhaps return array of bytes?] function read($bytes) { return false; } - + // should return new position function seekto($position) { return false; } - + // returns current position function currentpos() { return false; } - + // returns length of entire stream (limit for seekto()s) function length() { return false; } -} +}; class StringReader { var $_pos; @@ -78,7 +78,7 @@ class StringReader { return strlen($this->_str); } -} +}; class FileReader { @@ -93,8 +93,8 @@ class FileReader { $this->_pos = 0; $this->_fd = fopen($filename,'rb'); if (!$this->_fd) { - $this->error = 3; // Cannot read file, probably permissions - return false; + $this->error = 3; // Cannot read file, probably permissions + return false; } } else { $this->error = 2; // File doesn't exist @@ -108,14 +108,14 @@ class FileReader { // PHP 5.1.1 does not read more than 8192 bytes in one fread() // the discussions at PHP Bugs suggest it's the intended behaviour - $data = ""; + $data = ''; while ($bytes > 0) { $chunk = fread($this->_fd, $bytes); $data .= $chunk; $bytes -= strlen($chunk); } $this->_pos = ftell($this->_fd); - + return $data; } else return ''; } @@ -138,9 +138,9 @@ class FileReader { fclose($this->_fd); } -} +}; -// Preloads entire file in memory first, then creates a StringReader +// Preloads entire file in memory first, then creates a StringReader // over it (it assumes knowledge of StringReader internals) class CachedFileReader extends StringReader { function CachedFileReader($filename) { @@ -150,8 +150,8 @@ class CachedFileReader extends StringReader { $fd = fopen($filename,'rb'); if (!$fd) { - $this->error = 3; // Cannot read file, probably permissions - return false; + $this->error = 3; // Cannot read file, probably permissions + return false; } $this->_str = fread($fd, $length); fclose($fd); @@ -161,7 +161,7 @@ class CachedFileReader extends StringReader { return false; } } -} +}; ?> diff --git a/lang.inc.php b/lang.inc.php index 1541fec8..c504a3e1 100644 --- a/lang.inc.php +++ b/lang.inc.php @@ -32,7 +32,7 @@ /** * The phpgettext package */ -require_once(dirname(__FILE__).'/include/php-gettext-1.0.7/gettext.inc'); +require_once(dirname(__FILE__).'/include/php-gettext-1.0.9/gettext.inc'); /** * Translate the given elements of the array