intl_error.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | http://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Vadim Savchuk <vsavchuk@productengine.com> |
  14. | Dmitry Lakhtyuk <dlakhtyuk@productengine.com> |
  15. | Stanislav Malyshev <stas@zend.com> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #include <php.h>
  22. #include <zend_exceptions.h>
  23. #include "php_intl.h"
  24. #include "intl_error.h"
  25. #include "intl_convert.h"
  26. ZEND_EXTERN_MODULE_GLOBALS( intl )
  27. static zend_class_entry *IntlException_ce_ptr;
  28. /* {{{ intl_error* intl_g_error_get()
  29. * Return global error structure.
  30. */
  31. static intl_error* intl_g_error_get( TSRMLS_D )
  32. {
  33. return &INTL_G( g_error );
  34. }
  35. /* }}} */
  36. /* {{{ void intl_free_custom_error_msg( intl_error* err )
  37. * Free mem.
  38. */
  39. static void intl_free_custom_error_msg( intl_error* err TSRMLS_DC )
  40. {
  41. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  42. return;
  43. if(err->free_custom_error_message ) {
  44. efree( err->custom_error_message );
  45. }
  46. err->custom_error_message = NULL;
  47. err->free_custom_error_message = 0;
  48. }
  49. /* }}} */
  50. /* {{{ intl_error* intl_error_create()
  51. * Create and initialize internals of 'intl_error'.
  52. */
  53. intl_error* intl_error_create( TSRMLS_D )
  54. {
  55. intl_error* err = ecalloc( 1, sizeof( intl_error ) );
  56. intl_error_init( err TSRMLS_CC );
  57. return err;
  58. }
  59. /* }}} */
  60. /* {{{ void intl_error_init( intl_error* coll_error )
  61. * Initialize internals of 'intl_error'.
  62. */
  63. void intl_error_init( intl_error* err TSRMLS_DC )
  64. {
  65. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  66. return;
  67. err->code = U_ZERO_ERROR;
  68. err->custom_error_message = NULL;
  69. err->free_custom_error_message = 0;
  70. }
  71. /* }}} */
  72. /* {{{ void intl_error_reset( intl_error* err )
  73. * Set last error code to 0 and unset last error message
  74. */
  75. void intl_error_reset( intl_error* err TSRMLS_DC )
  76. {
  77. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  78. return;
  79. err->code = U_ZERO_ERROR;
  80. intl_free_custom_error_msg( err TSRMLS_CC );
  81. }
  82. /* }}} */
  83. /* {{{ void intl_error_set_custom_msg( intl_error* err, char* msg, int copyMsg )
  84. * Set last error message to msg copying it if needed.
  85. */
  86. void intl_error_set_custom_msg( intl_error* err, char* msg, int copyMsg TSRMLS_DC )
  87. {
  88. if( !msg )
  89. return;
  90. if( !err ) {
  91. if( INTL_G( error_level ) )
  92. php_error_docref( NULL TSRMLS_CC, INTL_G( error_level ), "%s", msg );
  93. if( INTL_G( use_exceptions ) )
  94. zend_throw_exception_ex( IntlException_ce_ptr, 0 TSRMLS_CC, "%s", msg );
  95. }
  96. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  97. return;
  98. /* Free previous message if any */
  99. intl_free_custom_error_msg( err TSRMLS_CC );
  100. /* Mark message copied if any */
  101. err->free_custom_error_message = copyMsg;
  102. /* Set user's error text message */
  103. err->custom_error_message = copyMsg ? estrdup( msg ) : msg;
  104. }
  105. /* }}} */
  106. /* {{{ const char* intl_error_get_message( intl_error* err )
  107. * Create output message in format "<intl_error_text>: <extra_user_error_text>".
  108. */
  109. char* intl_error_get_message( intl_error* err TSRMLS_DC )
  110. {
  111. const char* uErrorName = NULL;
  112. char* errMessage = 0;
  113. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  114. return estrdup( "" );
  115. uErrorName = u_errorName( err->code );
  116. /* Format output string */
  117. if( err->custom_error_message )
  118. {
  119. spprintf( &errMessage, 0, "%s: %s", err->custom_error_message, uErrorName );
  120. }
  121. else
  122. {
  123. spprintf( &errMessage, 0, "%s", uErrorName );
  124. }
  125. return errMessage;
  126. }
  127. /* }}} */
  128. /* {{{ void intl_error_set_code( intl_error* err, UErrorCode err_code )
  129. * Set last error code.
  130. */
  131. void intl_error_set_code( intl_error* err, UErrorCode err_code TSRMLS_DC )
  132. {
  133. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  134. return;
  135. err->code = err_code;
  136. }
  137. /* }}} */
  138. /* {{{ void intl_error_get_code( intl_error* err )
  139. * Return last error code.
  140. */
  141. UErrorCode intl_error_get_code( intl_error* err TSRMLS_DC )
  142. {
  143. if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
  144. return U_ZERO_ERROR;
  145. return err->code;
  146. }
  147. /* }}} */
  148. /* {{{ void intl_error_set( intl_error* err, UErrorCode code, char* msg, int copyMsg )
  149. * Set error code and message.
  150. */
  151. void intl_error_set( intl_error* err, UErrorCode code, char* msg, int copyMsg TSRMLS_DC )
  152. {
  153. intl_error_set_code( err, code TSRMLS_CC );
  154. intl_error_set_custom_msg( err, msg, copyMsg TSRMLS_CC );
  155. }
  156. /* }}} */
  157. /* {{{ void intl_errors_set( intl_error* err, UErrorCode code, char* msg, int copyMsg )
  158. * Set error code and message.
  159. */
  160. void intl_errors_set( intl_error* err, UErrorCode code, char* msg, int copyMsg TSRMLS_DC )
  161. {
  162. intl_errors_set_code( err, code TSRMLS_CC );
  163. intl_errors_set_custom_msg( err, msg, copyMsg TSRMLS_CC );
  164. }
  165. /* }}} */
  166. /* {{{ void intl_errors_reset( intl_error* err )
  167. */
  168. void intl_errors_reset( intl_error* err TSRMLS_DC )
  169. {
  170. if(err) {
  171. intl_error_reset( err TSRMLS_CC );
  172. }
  173. intl_error_reset( NULL TSRMLS_CC );
  174. }
  175. /* }}} */
  176. /* {{{ void intl_errors_set_custom_msg( intl_error* err, char* msg, int copyMsg )
  177. */
  178. void intl_errors_set_custom_msg( intl_error* err, char* msg, int copyMsg TSRMLS_DC )
  179. {
  180. if(err) {
  181. intl_error_set_custom_msg( err, msg, copyMsg TSRMLS_CC );
  182. }
  183. intl_error_set_custom_msg( NULL, msg, copyMsg TSRMLS_CC );
  184. }
  185. /* }}} */
  186. /* {{{ intl_errors_set_code( intl_error* err, UErrorCode err_code )
  187. */
  188. void intl_errors_set_code( intl_error* err, UErrorCode err_code TSRMLS_DC )
  189. {
  190. if(err) {
  191. intl_error_set_code( err, err_code TSRMLS_CC );
  192. }
  193. intl_error_set_code( NULL, err_code TSRMLS_CC );
  194. }
  195. /* }}} */
  196. void intl_register_IntlException_class( TSRMLS_D )
  197. {
  198. zend_class_entry ce,
  199. *default_exception_ce;
  200. default_exception_ce = zend_exception_get_default( TSRMLS_C );
  201. /* Create and register 'IntlException' class. */
  202. INIT_CLASS_ENTRY_EX( ce, "IntlException", sizeof( "IntlException" ) - 1, NULL );
  203. IntlException_ce_ptr = zend_register_internal_class_ex( &ce,
  204. default_exception_ce, NULL TSRMLS_CC );
  205. IntlException_ce_ptr->create_object = default_exception_ce->create_object;
  206. }
  207. smart_str intl_parse_error_to_string( UParseError* pe )
  208. {
  209. smart_str ret = {0};
  210. char *buf;
  211. int u8len;
  212. UErrorCode status;
  213. int any = 0;
  214. assert( pe != NULL );
  215. smart_str_appends( &ret, "parse error " );
  216. if( pe->line > 0 )
  217. {
  218. smart_str_appends( &ret, "on line " );
  219. smart_str_append_long( &ret, (long ) pe->line );
  220. any = 1;
  221. }
  222. if( pe->offset >= 0 ) {
  223. if( any )
  224. smart_str_appends( &ret, ", " );
  225. else
  226. smart_str_appends( &ret, "at " );
  227. smart_str_appends( &ret, "offset " );
  228. smart_str_append_long( &ret, (long ) pe->offset );
  229. any = 1;
  230. }
  231. if (pe->preContext[0] != 0 ) {
  232. if( any )
  233. smart_str_appends( &ret, ", " );
  234. smart_str_appends( &ret, "after \"" );
  235. intl_convert_utf16_to_utf8( &buf, &u8len, pe->preContext, -1, &status );
  236. if( U_FAILURE( status ) )
  237. {
  238. smart_str_appends( &ret, "(could not convert parser error pre-context to UTF-8)" );
  239. }
  240. else {
  241. smart_str_appendl( &ret, buf, u8len );
  242. efree( buf );
  243. }
  244. smart_str_appends( &ret, "\"" );
  245. any = 1;
  246. }
  247. if( pe->postContext[0] != 0 )
  248. {
  249. if( any )
  250. smart_str_appends( &ret, ", " );
  251. smart_str_appends( &ret, "before or at \"" );
  252. intl_convert_utf16_to_utf8( &buf, &u8len, pe->postContext, -1, &status );
  253. if( U_FAILURE( status ) )
  254. {
  255. smart_str_appends( &ret, "(could not convert parser error post-context to UTF-8)" );
  256. }
  257. else
  258. {
  259. smart_str_appendl( &ret, buf, u8len );
  260. efree( buf );
  261. }
  262. smart_str_appends( &ret, "\"" );
  263. any = 1;
  264. }
  265. if( !any )
  266. {
  267. smart_str_free( &ret );
  268. smart_str_appends( &ret, "no parse error" );
  269. }
  270. smart_str_0( &ret );
  271. return ret;
  272. }
  273. /*
  274. * Local variables:
  275. * tab-width: 4
  276. * c-basic-offset: 4
  277. * End:
  278. * vim600: noet sw=4 ts=4 fdm=marker
  279. * vim<600: noet sw=4 ts=4
  280. */