Back to index

php5  5.3.10
gettext.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Alex Plotnick <alex@wgate.com>                               |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: gettext.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #include "php.h"
00026 
00027 #if HAVE_LIBINTL
00028 
00029 #include <stdio.h>
00030 #include "ext/standard/info.h"
00031 #include "php_gettext.h"
00032 
00033 /* {{{ arginfo */
00034 ZEND_BEGIN_ARG_INFO(arginfo_textdomain, 0)
00035        ZEND_ARG_INFO(0, domain)
00036 ZEND_END_ARG_INFO()
00037 
00038 ZEND_BEGIN_ARG_INFO(arginfo_gettext, 0)
00039        ZEND_ARG_INFO(0, msgid)
00040 ZEND_END_ARG_INFO()
00041 
00042 ZEND_BEGIN_ARG_INFO(arginfo_dgettext, 0)
00043        ZEND_ARG_INFO(0, domain_name)
00044        ZEND_ARG_INFO(0, msgid)
00045 ZEND_END_ARG_INFO()
00046 
00047 ZEND_BEGIN_ARG_INFO(arginfo_dcgettext, 0)
00048        ZEND_ARG_INFO(0, domain_name)
00049        ZEND_ARG_INFO(0, msgid)
00050        ZEND_ARG_INFO(0, category)
00051 ZEND_END_ARG_INFO()
00052 
00053 ZEND_BEGIN_ARG_INFO(arginfo_bindtextdomain, 0)
00054        ZEND_ARG_INFO(0, domain_name)
00055        ZEND_ARG_INFO(0, dir)
00056 ZEND_END_ARG_INFO()
00057 
00058 #if HAVE_NGETTEXT
00059 ZEND_BEGIN_ARG_INFO(arginfo_ngettext, 0)
00060        ZEND_ARG_INFO(0, msgid1)
00061        ZEND_ARG_INFO(0, msgid2)
00062        ZEND_ARG_INFO(0, count)
00063 ZEND_END_ARG_INFO()
00064 #endif
00065 
00066 #if HAVE_DNGETTEXT
00067 ZEND_BEGIN_ARG_INFO(arginfo_dngettext, 0)
00068        ZEND_ARG_INFO(0, domain)
00069        ZEND_ARG_INFO(0, msgid1)
00070        ZEND_ARG_INFO(0, msgid2)
00071        ZEND_ARG_INFO(0, count)
00072 ZEND_END_ARG_INFO()
00073 #endif
00074 
00075 #if HAVE_DCNGETTEXT
00076 ZEND_BEGIN_ARG_INFO(arginfo_dcngettext, 0)
00077        ZEND_ARG_INFO(0, domain)
00078        ZEND_ARG_INFO(0, msgid1)
00079        ZEND_ARG_INFO(0, msgid2)
00080        ZEND_ARG_INFO(0, count)
00081        ZEND_ARG_INFO(0, category)
00082 ZEND_END_ARG_INFO()
00083 #endif
00084 
00085 #if HAVE_BIND_TEXTDOMAIN_CODESET
00086 ZEND_BEGIN_ARG_INFO(arginfo_bind_textdomain_codeset, 0)
00087        ZEND_ARG_INFO(0, domain)
00088        ZEND_ARG_INFO(0, codeset)
00089 ZEND_END_ARG_INFO()
00090 #endif
00091 /* }}} */
00092 
00093 /* {{{ php_gettext_functions[]
00094  */
00095 const zend_function_entry php_gettext_functions[] = {
00096        PHP_NAMED_FE(textdomain,           zif_textdomain,             arginfo_textdomain)
00097        PHP_NAMED_FE(gettext,                     zif_gettext,         arginfo_gettext)
00098        /* Alias for gettext() */
00099        PHP_NAMED_FE(_,                                  zif_gettext,         arginfo_gettext)
00100        PHP_NAMED_FE(dgettext,                    zif_dgettext,        arginfo_dgettext)
00101        PHP_NAMED_FE(dcgettext,                   zif_dcgettext,              arginfo_dcgettext)
00102        PHP_NAMED_FE(bindtextdomain,       zif_bindtextdomain,  arginfo_bindtextdomain)
00103 #if HAVE_NGETTEXT
00104        PHP_NAMED_FE(ngettext,                    zif_ngettext,        arginfo_ngettext)
00105 #endif
00106 #if HAVE_DNGETTEXT
00107        PHP_NAMED_FE(dngettext,                   zif_dngettext,              arginfo_dngettext)
00108 #endif
00109 #if HAVE_DCNGETTEXT
00110        PHP_NAMED_FE(dcngettext,           zif_dcngettext,             arginfo_dcngettext)
00111 #endif
00112 #if HAVE_BIND_TEXTDOMAIN_CODESET
00113        PHP_NAMED_FE(bind_textdomain_codeset,     zif_bind_textdomain_codeset,       arginfo_bind_textdomain_codeset)
00114 #endif
00115     PHP_FE_END
00116 };
00117 /* }}} */
00118 
00119 #include <libintl.h>
00120 
00121 zend_module_entry php_gettext_module_entry = {
00122        STANDARD_MODULE_HEADER,
00123        "gettext",
00124        php_gettext_functions,
00125        NULL,
00126        NULL,
00127        NULL,
00128        NULL,
00129        PHP_MINFO(php_gettext),
00130        NO_VERSION_YET,
00131        STANDARD_MODULE_PROPERTIES
00132 };
00133 
00134 #ifdef COMPILE_DL_GETTEXT
00135 ZEND_GET_MODULE(php_gettext)
00136 #endif
00137 
00138 #define PHP_GETTEXT_MAX_DOMAIN_LENGTH 1024
00139 #define PHP_GETTEXT_MAX_MSGID_LENGTH 4096
00140 
00141 #define PHP_GETTEXT_DOMAIN_LENGTH_CHECK \
00142        if (domain_len > PHP_GETTEXT_MAX_DOMAIN_LENGTH) { \
00143               php_error_docref(NULL TSRMLS_CC, E_WARNING, "domain passed too long"); \
00144               RETURN_FALSE; \
00145        }
00146 
00147 #define PHP_GETTEXT_LENGTH_CHECK(check_name, check_len) \
00148        if (check_len > PHP_GETTEXT_MAX_MSGID_LENGTH) { \
00149               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s passed too long", check_name); \
00150               RETURN_FALSE; \
00151        }
00152 
00153 PHP_MINFO_FUNCTION(php_gettext)
00154 {
00155        php_info_print_table_start();
00156        php_info_print_table_row(2, "GetText Support", "enabled");
00157        php_info_print_table_end();
00158 }
00159 
00160 /* {{{ proto string textdomain(string domain)
00161    Set the textdomain to "domain". Returns the current domain */
00162 PHP_NAMED_FUNCTION(zif_textdomain)
00163 {
00164        char *domain, *domain_name, *retval;
00165        int domain_len;
00166 
00167        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &domain, &domain_len) == FAILURE) {
00168               return;
00169        }
00170 
00171        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00172 
00173        if (strcmp(domain, "") && strcmp(domain, "0")) {
00174               domain_name = domain;
00175        } else {
00176               domain_name = NULL;
00177        }
00178 
00179        retval = textdomain(domain_name);
00180 
00181        RETURN_STRING(retval, 1);
00182 }
00183 /* }}} */
00184 
00185 /* {{{ proto string gettext(string msgid)
00186    Return the translation of msgid for the current domain, or msgid unaltered if a translation does not exist */
00187 PHP_NAMED_FUNCTION(zif_gettext)
00188 {
00189        char *msgid, *msgstr;
00190        int msgid_len;
00191 
00192        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msgid, &msgid_len) == FAILURE) {
00193               return;
00194        }
00195 
00196        PHP_GETTEXT_LENGTH_CHECK("msgid", msgid_len)
00197        msgstr = gettext(msgid);
00198 
00199        RETURN_STRING(msgstr, 1);
00200 }
00201 /* }}} */
00202 
00203 /* {{{ proto string dgettext(string domain_name, string msgid)
00204    Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist */
00205 PHP_NAMED_FUNCTION(zif_dgettext)
00206 {
00207        char *domain, *msgid, *msgstr;
00208        int domain_len, msgid_len;
00209 
00210        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &msgid, &msgid_len) == FAILURE)       {
00211               return;
00212        }
00213 
00214        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00215        PHP_GETTEXT_LENGTH_CHECK("msgid", msgid_len)
00216 
00217        msgstr = dgettext(domain, msgid);
00218 
00219        RETURN_STRING(msgstr, 1);
00220 }
00221 /* }}} */
00222 
00223 /* {{{ proto string dcgettext(string domain_name, string msgid, long category)
00224    Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist */
00225 PHP_NAMED_FUNCTION(zif_dcgettext)
00226 {
00227        char *domain, *msgid, *msgstr;
00228        int domain_len, msgid_len;
00229        long category;
00230 
00231        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &domain, &domain_len, &msgid, &msgid_len, &category) == FAILURE) {
00232               return;
00233        }
00234 
00235        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00236        PHP_GETTEXT_LENGTH_CHECK("msgid", msgid_len)
00237 
00238        msgstr = dcgettext(domain, msgid, category);
00239 
00240        RETURN_STRING(msgstr, 1);
00241 }
00242 /* }}} */
00243 
00244 /* {{{ proto string bindtextdomain(string domain_name, string dir)
00245    Bind to the text domain domain_name, looking for translations in dir. Returns the current domain */
00246 PHP_NAMED_FUNCTION(zif_bindtextdomain)
00247 {
00248        char *domain, *dir;
00249        int domain_len, dir_len;
00250        char *retval, dir_name[MAXPATHLEN];
00251 
00252        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &dir, &dir_len) == FAILURE) {
00253               return;
00254        }
00255 
00256        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00257 
00258        if (domain[0] == '\0') {
00259               php_error(E_WARNING, "The first parameter of bindtextdomain must not be empty");
00260               RETURN_FALSE;
00261        }
00262 
00263        if (dir[0] != '\0' && strcmp(dir, "0")) {
00264               if (!VCWD_REALPATH(dir, dir_name)) {
00265                      RETURN_FALSE;
00266               }
00267        } else if (!VCWD_GETCWD(dir_name, MAXPATHLEN)) {
00268               RETURN_FALSE;
00269        }
00270 
00271        retval = bindtextdomain(domain, dir_name);
00272 
00273        RETURN_STRING(retval, 1);
00274 }
00275 /* }}} */
00276 
00277 #if HAVE_NGETTEXT
00278 /* {{{ proto string ngettext(string MSGID1, string MSGID2, int N)
00279    Plural version of gettext() */
00280 PHP_NAMED_FUNCTION(zif_ngettext)
00281 {
00282        char *msgid1, *msgid2, *msgstr;
00283        int msgid1_len, msgid2_len;
00284        long count;
00285 
00286        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) {
00287               return;
00288        }
00289 
00290        PHP_GETTEXT_LENGTH_CHECK("msgid1", msgid1_len)
00291        PHP_GETTEXT_LENGTH_CHECK("msgid2", msgid2_len)
00292 
00293        msgstr = ngettext(msgid1, msgid2, count);
00294        if (msgstr) {
00295               RETVAL_STRING(msgstr, 1);
00296        }
00297 }
00298 /* }}} */
00299 #endif
00300 
00301 #if HAVE_DNGETTEXT
00302 /* {{{ proto string dngettext (string domain, string msgid1, string msgid2, int count)
00303    Plural version of dgettext() */
00304 PHP_NAMED_FUNCTION(zif_dngettext)
00305 {
00306        char *domain, *msgid1, *msgid2, *msgstr = NULL;
00307        int domain_len, msgid1_len, msgid2_len;
00308        long count;
00309 
00310        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl", &domain, &domain_len,
00311               &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) {
00312               return;
00313        }
00314 
00315        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00316        PHP_GETTEXT_LENGTH_CHECK("msgid1", msgid1_len)
00317        PHP_GETTEXT_LENGTH_CHECK("msgid2", msgid2_len)
00318 
00319        msgstr = dngettext(domain, msgid1, msgid2, count);
00320        if (msgstr) {
00321               RETVAL_STRING(msgstr, 1);
00322        }
00323 }
00324 /* }}} */
00325 #endif
00326 
00327 #if HAVE_DCNGETTEXT
00328 /* {{{ proto string dcngettext (string domain, string msgid1, string msgid2, int n, int category)
00329    Plural version of dcgettext() */
00330 PHP_NAMED_FUNCTION(zif_dcngettext)
00331 {
00332        char *domain, *msgid1, *msgid2, *msgstr = NULL;
00333        int domain_len, msgid1_len, msgid2_len;
00334        long count, category;
00335 
00336        RETVAL_FALSE;
00337 
00338        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssll", &domain, &domain_len,
00339               &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count, &category) == FAILURE) {
00340               return;
00341        }
00342 
00343        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00344        PHP_GETTEXT_LENGTH_CHECK("msgid1", msgid1_len)
00345        PHP_GETTEXT_LENGTH_CHECK("msgid2", msgid2_len)
00346 
00347        msgstr = dcngettext(domain, msgid1, msgid2, count, category);
00348 
00349        if (msgstr) {
00350               RETVAL_STRING(msgstr, 1);
00351        }
00352 }
00353 /* }}} */
00354 #endif
00355 
00356 #if HAVE_BIND_TEXTDOMAIN_CODESET
00357 
00358 /* {{{ proto string bind_textdomain_codeset (string domain, string codeset)
00359    Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. */
00360 PHP_NAMED_FUNCTION(zif_bind_textdomain_codeset)
00361 {
00362        char *domain, *codeset, *retval = NULL;
00363        int domain_len, codeset_len;
00364 
00365        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &codeset, &codeset_len) == FAILURE) {
00366               return;
00367        }
00368 
00369        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
00370 
00371        retval = bind_textdomain_codeset(domain, codeset);
00372 
00373        if (!retval) {
00374               RETURN_FALSE;
00375        }
00376        RETURN_STRING(retval, 1);
00377 }
00378 /* }}} */
00379 #endif
00380 
00381 
00382 #endif /* HAVE_LIBINTL */
00383 
00384 /*
00385  * Local variables:
00386  * tab-width: 4
00387  * c-basic-offset: 4
00388  * End:
00389  * vim600: sw=4 ts=4 fdm=marker
00390  * vim<600: sw=4 ts=4
00391  */
00392