Return to gettext.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / gettext |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Author: Alex Plotnick <alex@wgate.com> | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: /* $Id: gettext.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 20: ! 21: #ifdef HAVE_CONFIG_H ! 22: #include "config.h" ! 23: #endif ! 24: ! 25: #include "php.h" ! 26: ! 27: #if HAVE_LIBINTL ! 28: ! 29: #include <stdio.h> ! 30: #include "ext/standard/info.h" ! 31: #include "php_gettext.h" ! 32: ! 33: /* {{{ arginfo */ ! 34: ZEND_BEGIN_ARG_INFO(arginfo_textdomain, 0) ! 35: ZEND_ARG_INFO(0, domain) ! 36: ZEND_END_ARG_INFO() ! 37: ! 38: ZEND_BEGIN_ARG_INFO(arginfo_gettext, 0) ! 39: ZEND_ARG_INFO(0, msgid) ! 40: ZEND_END_ARG_INFO() ! 41: ! 42: ZEND_BEGIN_ARG_INFO(arginfo_dgettext, 0) ! 43: ZEND_ARG_INFO(0, domain_name) ! 44: ZEND_ARG_INFO(0, msgid) ! 45: ZEND_END_ARG_INFO() ! 46: ! 47: ZEND_BEGIN_ARG_INFO(arginfo_dcgettext, 0) ! 48: ZEND_ARG_INFO(0, domain_name) ! 49: ZEND_ARG_INFO(0, msgid) ! 50: ZEND_ARG_INFO(0, category) ! 51: ZEND_END_ARG_INFO() ! 52: ! 53: ZEND_BEGIN_ARG_INFO(arginfo_bindtextdomain, 0) ! 54: ZEND_ARG_INFO(0, domain_name) ! 55: ZEND_ARG_INFO(0, dir) ! 56: ZEND_END_ARG_INFO() ! 57: ! 58: #if HAVE_NGETTEXT ! 59: ZEND_BEGIN_ARG_INFO(arginfo_ngettext, 0) ! 60: ZEND_ARG_INFO(0, msgid1) ! 61: ZEND_ARG_INFO(0, msgid2) ! 62: ZEND_ARG_INFO(0, count) ! 63: ZEND_END_ARG_INFO() ! 64: #endif ! 65: ! 66: #if HAVE_DNGETTEXT ! 67: ZEND_BEGIN_ARG_INFO(arginfo_dngettext, 0) ! 68: ZEND_ARG_INFO(0, domain) ! 69: ZEND_ARG_INFO(0, msgid1) ! 70: ZEND_ARG_INFO(0, msgid2) ! 71: ZEND_ARG_INFO(0, count) ! 72: ZEND_END_ARG_INFO() ! 73: #endif ! 74: ! 75: #if HAVE_DCNGETTEXT ! 76: ZEND_BEGIN_ARG_INFO(arginfo_dcngettext, 0) ! 77: ZEND_ARG_INFO(0, domain) ! 78: ZEND_ARG_INFO(0, msgid1) ! 79: ZEND_ARG_INFO(0, msgid2) ! 80: ZEND_ARG_INFO(0, count) ! 81: ZEND_ARG_INFO(0, category) ! 82: ZEND_END_ARG_INFO() ! 83: #endif ! 84: ! 85: #if HAVE_BIND_TEXTDOMAIN_CODESET ! 86: ZEND_BEGIN_ARG_INFO(arginfo_bind_textdomain_codeset, 0) ! 87: ZEND_ARG_INFO(0, domain) ! 88: ZEND_ARG_INFO(0, codeset) ! 89: ZEND_END_ARG_INFO() ! 90: #endif ! 91: /* }}} */ ! 92: ! 93: /* {{{ php_gettext_functions[] ! 94: */ ! 95: const zend_function_entry php_gettext_functions[] = { ! 96: PHP_NAMED_FE(textdomain, zif_textdomain, arginfo_textdomain) ! 97: PHP_NAMED_FE(gettext, zif_gettext, arginfo_gettext) ! 98: /* Alias for gettext() */ ! 99: PHP_NAMED_FE(_, zif_gettext, arginfo_gettext) ! 100: PHP_NAMED_FE(dgettext, zif_dgettext, arginfo_dgettext) ! 101: PHP_NAMED_FE(dcgettext, zif_dcgettext, arginfo_dcgettext) ! 102: PHP_NAMED_FE(bindtextdomain, zif_bindtextdomain, arginfo_bindtextdomain) ! 103: #if HAVE_NGETTEXT ! 104: PHP_NAMED_FE(ngettext, zif_ngettext, arginfo_ngettext) ! 105: #endif ! 106: #if HAVE_DNGETTEXT ! 107: PHP_NAMED_FE(dngettext, zif_dngettext, arginfo_dngettext) ! 108: #endif ! 109: #if HAVE_DCNGETTEXT ! 110: PHP_NAMED_FE(dcngettext, zif_dcngettext, arginfo_dcngettext) ! 111: #endif ! 112: #if HAVE_BIND_TEXTDOMAIN_CODESET ! 113: PHP_NAMED_FE(bind_textdomain_codeset, zif_bind_textdomain_codeset, arginfo_bind_textdomain_codeset) ! 114: #endif ! 115: PHP_FE_END ! 116: }; ! 117: /* }}} */ ! 118: ! 119: #include <libintl.h> ! 120: ! 121: zend_module_entry php_gettext_module_entry = { ! 122: STANDARD_MODULE_HEADER, ! 123: "gettext", ! 124: php_gettext_functions, ! 125: NULL, ! 126: NULL, ! 127: NULL, ! 128: NULL, ! 129: PHP_MINFO(php_gettext), ! 130: NO_VERSION_YET, ! 131: STANDARD_MODULE_PROPERTIES ! 132: }; ! 133: ! 134: #ifdef COMPILE_DL_GETTEXT ! 135: ZEND_GET_MODULE(php_gettext) ! 136: #endif ! 137: ! 138: #define PHP_GETTEXT_MAX_DOMAIN_LENGTH 1024 ! 139: #define PHP_GETTEXT_MAX_MSGID_LENGTH 4096 ! 140: ! 141: #define PHP_GETTEXT_DOMAIN_LENGTH_CHECK \ ! 142: if (domain_len > PHP_GETTEXT_MAX_DOMAIN_LENGTH) { \ ! 143: php_error_docref(NULL TSRMLS_CC, E_WARNING, "domain passed too long"); \ ! 144: RETURN_FALSE; \ ! 145: } ! 146: ! 147: #define PHP_GETTEXT_LENGTH_CHECK(check_name, check_len) \ ! 148: if (check_len > PHP_GETTEXT_MAX_MSGID_LENGTH) { \ ! 149: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s passed too long", check_name); \ ! 150: RETURN_FALSE; \ ! 151: } ! 152: ! 153: PHP_MINFO_FUNCTION(php_gettext) ! 154: { ! 155: php_info_print_table_start(); ! 156: php_info_print_table_row(2, "GetText Support", "enabled"); ! 157: php_info_print_table_end(); ! 158: } ! 159: ! 160: /* {{{ proto string textdomain(string domain) ! 161: Set the textdomain to "domain". Returns the current domain */ ! 162: PHP_NAMED_FUNCTION(zif_textdomain) ! 163: { ! 164: char *domain, *domain_name, *retval; ! 165: int domain_len; ! 166: ! 167: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &domain, &domain_len) == FAILURE) { ! 168: return; ! 169: } ! 170: ! 171: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 172: ! 173: if (strcmp(domain, "") && strcmp(domain, "0")) { ! 174: domain_name = domain; ! 175: } else { ! 176: domain_name = NULL; ! 177: } ! 178: ! 179: retval = textdomain(domain_name); ! 180: ! 181: RETURN_STRING(retval, 1); ! 182: } ! 183: /* }}} */ ! 184: ! 185: /* {{{ proto string gettext(string msgid) ! 186: Return the translation of msgid for the current domain, or msgid unaltered if a translation does not exist */ ! 187: PHP_NAMED_FUNCTION(zif_gettext) ! 188: { ! 189: char *msgid, *msgstr; ! 190: int msgid_len; ! 191: ! 192: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msgid, &msgid_len) == FAILURE) { ! 193: return; ! 194: } ! 195: ! 196: PHP_GETTEXT_LENGTH_CHECK("msgid", msgid_len) ! 197: msgstr = gettext(msgid); ! 198: ! 199: RETURN_STRING(msgstr, 1); ! 200: } ! 201: /* }}} */ ! 202: ! 203: /* {{{ proto string dgettext(string domain_name, string msgid) ! 204: Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist */ ! 205: PHP_NAMED_FUNCTION(zif_dgettext) ! 206: { ! 207: char *domain, *msgid, *msgstr; ! 208: int domain_len, msgid_len; ! 209: ! 210: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &msgid, &msgid_len) == FAILURE) { ! 211: return; ! 212: } ! 213: ! 214: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 215: PHP_GETTEXT_LENGTH_CHECK("msgid", msgid_len) ! 216: ! 217: msgstr = dgettext(domain, msgid); ! 218: ! 219: RETURN_STRING(msgstr, 1); ! 220: } ! 221: /* }}} */ ! 222: ! 223: /* {{{ proto string dcgettext(string domain_name, string msgid, long category) ! 224: Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist */ ! 225: PHP_NAMED_FUNCTION(zif_dcgettext) ! 226: { ! 227: char *domain, *msgid, *msgstr; ! 228: int domain_len, msgid_len; ! 229: long category; ! 230: ! 231: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &domain, &domain_len, &msgid, &msgid_len, &category) == FAILURE) { ! 232: return; ! 233: } ! 234: ! 235: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 236: PHP_GETTEXT_LENGTH_CHECK("msgid", msgid_len) ! 237: ! 238: msgstr = dcgettext(domain, msgid, category); ! 239: ! 240: RETURN_STRING(msgstr, 1); ! 241: } ! 242: /* }}} */ ! 243: ! 244: /* {{{ proto string bindtextdomain(string domain_name, string dir) ! 245: Bind to the text domain domain_name, looking for translations in dir. Returns the current domain */ ! 246: PHP_NAMED_FUNCTION(zif_bindtextdomain) ! 247: { ! 248: char *domain, *dir; ! 249: int domain_len, dir_len; ! 250: char *retval, dir_name[MAXPATHLEN]; ! 251: ! 252: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &dir, &dir_len) == FAILURE) { ! 253: return; ! 254: } ! 255: ! 256: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 257: ! 258: if (domain[0] == '\0') { ! 259: php_error(E_WARNING, "The first parameter of bindtextdomain must not be empty"); ! 260: RETURN_FALSE; ! 261: } ! 262: ! 263: if (dir[0] != '\0' && strcmp(dir, "0")) { ! 264: if (!VCWD_REALPATH(dir, dir_name)) { ! 265: RETURN_FALSE; ! 266: } ! 267: } else if (!VCWD_GETCWD(dir_name, MAXPATHLEN)) { ! 268: RETURN_FALSE; ! 269: } ! 270: ! 271: retval = bindtextdomain(domain, dir_name); ! 272: ! 273: RETURN_STRING(retval, 1); ! 274: } ! 275: /* }}} */ ! 276: ! 277: #if HAVE_NGETTEXT ! 278: /* {{{ proto string ngettext(string MSGID1, string MSGID2, int N) ! 279: Plural version of gettext() */ ! 280: PHP_NAMED_FUNCTION(zif_ngettext) ! 281: { ! 282: char *msgid1, *msgid2, *msgstr; ! 283: int msgid1_len, msgid2_len; ! 284: long count; ! 285: ! 286: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) { ! 287: return; ! 288: } ! 289: ! 290: PHP_GETTEXT_LENGTH_CHECK("msgid1", msgid1_len) ! 291: PHP_GETTEXT_LENGTH_CHECK("msgid2", msgid2_len) ! 292: ! 293: msgstr = ngettext(msgid1, msgid2, count); ! 294: if (msgstr) { ! 295: RETVAL_STRING(msgstr, 1); ! 296: } ! 297: } ! 298: /* }}} */ ! 299: #endif ! 300: ! 301: #if HAVE_DNGETTEXT ! 302: /* {{{ proto string dngettext (string domain, string msgid1, string msgid2, int count) ! 303: Plural version of dgettext() */ ! 304: PHP_NAMED_FUNCTION(zif_dngettext) ! 305: { ! 306: char *domain, *msgid1, *msgid2, *msgstr = NULL; ! 307: int domain_len, msgid1_len, msgid2_len; ! 308: long count; ! 309: ! 310: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl", &domain, &domain_len, ! 311: &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) { ! 312: return; ! 313: } ! 314: ! 315: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 316: PHP_GETTEXT_LENGTH_CHECK("msgid1", msgid1_len) ! 317: PHP_GETTEXT_LENGTH_CHECK("msgid2", msgid2_len) ! 318: ! 319: msgstr = dngettext(domain, msgid1, msgid2, count); ! 320: if (msgstr) { ! 321: RETVAL_STRING(msgstr, 1); ! 322: } ! 323: } ! 324: /* }}} */ ! 325: #endif ! 326: ! 327: #if HAVE_DCNGETTEXT ! 328: /* {{{ proto string dcngettext (string domain, string msgid1, string msgid2, int n, int category) ! 329: Plural version of dcgettext() */ ! 330: PHP_NAMED_FUNCTION(zif_dcngettext) ! 331: { ! 332: char *domain, *msgid1, *msgid2, *msgstr = NULL; ! 333: int domain_len, msgid1_len, msgid2_len; ! 334: long count, category; ! 335: ! 336: RETVAL_FALSE; ! 337: ! 338: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssll", &domain, &domain_len, ! 339: &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count, &category) == FAILURE) { ! 340: return; ! 341: } ! 342: ! 343: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 344: PHP_GETTEXT_LENGTH_CHECK("msgid1", msgid1_len) ! 345: PHP_GETTEXT_LENGTH_CHECK("msgid2", msgid2_len) ! 346: ! 347: msgstr = dcngettext(domain, msgid1, msgid2, count, category); ! 348: ! 349: if (msgstr) { ! 350: RETVAL_STRING(msgstr, 1); ! 351: } ! 352: } ! 353: /* }}} */ ! 354: #endif ! 355: ! 356: #if HAVE_BIND_TEXTDOMAIN_CODESET ! 357: ! 358: /* {{{ proto string bind_textdomain_codeset (string domain, string codeset) ! 359: Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. */ ! 360: PHP_NAMED_FUNCTION(zif_bind_textdomain_codeset) ! 361: { ! 362: char *domain, *codeset, *retval = NULL; ! 363: int domain_len, codeset_len; ! 364: ! 365: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &codeset, &codeset_len) == FAILURE) { ! 366: return; ! 367: } ! 368: ! 369: PHP_GETTEXT_DOMAIN_LENGTH_CHECK ! 370: ! 371: retval = bind_textdomain_codeset(domain, codeset); ! 372: ! 373: if (!retval) { ! 374: RETURN_FALSE; ! 375: } ! 376: RETURN_STRING(retval, 1); ! 377: } ! 378: /* }}} */ ! 379: #endif ! 380: ! 381: ! 382: #endif /* HAVE_LIBINTL */ ! 383: ! 384: /* ! 385: * Local variables: ! 386: * tab-width: 4 ! 387: * c-basic-offset: 4 ! 388: * End: ! 389: * vim600: sw=4 ts=4 fdm=marker ! 390: * vim<600: sw=4 ts=4 ! 391: */ ! 392: