You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3225 lines
78 KiB

27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP version 4.0 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997, 1998, 1999 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.0 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://www.php.net/license/2_0.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. | Authors: Andi Gutmans <andi@zend.com> |
  16. | Zeev Suraski <zeev@zend.com> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "php.h"
  20. #include "php_ini.h"
  21. #include "internal_functions_registry.h"
  22. #include "php3_standard.h"
  23. #include "zend_operators.h"
  24. #include <stdarg.h>
  25. #include <stdlib.h>
  26. #include <math.h>
  27. #include <time.h>
  28. #include <stdio.h>
  29. #if HAVE_UNISTD_H
  30. #include <unistd.h>
  31. #endif
  32. #if HAVE_STRING_H
  33. #include <string.h>
  34. #else
  35. #include <strings.h>
  36. #endif
  37. #include "safe_mode.h"
  38. #if WIN32|WINNT
  39. #include "win32/unistd.h"
  40. #endif
  41. #include "zend_globals.h"
  42. #include "php_globals.h"
  43. #include "SAPI.h"
  44. #if APACHE
  45. /*
  46. ap_compat.h does a
  47. #define md5 ap_md5
  48. which "kills" out md5 function.
  49. */
  50. #ifdef md5
  51. #undef md5
  52. #endif
  53. #endif
  54. static unsigned char second_and_third_args_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_FORCE };
  55. /* uncomment this if/when we actually need it - tired of seeing the warning
  56. static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE };
  57. */
  58. static pval *user_compare_func_name;
  59. static HashTable *user_shutdown_function_names;
  60. typedef struct _php_shutdown_function_entry {
  61. zval **arguments;
  62. int arg_count;
  63. } php_shutdown_function_entry;
  64. /* some prototypes for local functions */
  65. int user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry);
  66. void php3_call_shutdown_functions(void);
  67. function_entry basic_functions[] = {
  68. PHP_FE(intval, NULL)
  69. PHP_FE(doubleval, NULL)
  70. PHP_FE(strval, NULL)
  71. PHP_FE(bin2hex, NULL)
  72. PHP_FE(toggle_short_open_tag, NULL)
  73. PHP_FE(sleep, NULL)
  74. PHP_FE(usleep, NULL)
  75. PHP_FE(ksort, first_arg_force_ref)
  76. PHP_FE(krsort, first_arg_force_ref)
  77. PHP_FE(asort, first_arg_force_ref)
  78. PHP_FE(arsort, first_arg_force_ref)
  79. PHP_FE(sort, first_arg_force_ref)
  80. PHP_FE(rsort, first_arg_force_ref)
  81. PHP_FE(usort, first_arg_force_ref)
  82. PHP_FE(uasort, first_arg_force_ref)
  83. PHP_FE(uksort, first_arg_force_ref)
  84. PHP_FE(shuffle, first_arg_force_ref)
  85. PHP_FE(array_walk, first_arg_force_ref)
  86. PHP_FALIAS(sizeof, count, first_arg_allow_ref)
  87. PHP_FE(count, first_arg_allow_ref)
  88. PHP_FE(end, first_arg_force_ref)
  89. PHP_FE(prev, first_arg_force_ref)
  90. PHP_FE(next, first_arg_force_ref)
  91. PHP_FE(reset, first_arg_force_ref)
  92. PHP_FE(current, first_arg_force_ref)
  93. PHP_FE(key, first_arg_force_ref)
  94. PHP_FALIAS(pos, current, first_arg_force_ref)
  95. PHP_FE(time, NULL)
  96. PHP_FE(mktime, NULL)
  97. PHP_FE(gmmktime, NULL)
  98. #if HAVE_STRFTIME
  99. PHP_FE(strftime, NULL)
  100. #endif
  101. PHP_FE(strtotime, NULL)
  102. PHP_FE(date, NULL)
  103. PHP_FE(gmdate, NULL)
  104. PHP_FE(getdate, NULL)
  105. PHP_FE(checkdate, NULL)
  106. PHP_FE(flush, NULL)
  107. PHP_FE(gettype, NULL)
  108. PHP_FE(settype, first_arg_force_ref)
  109. PHP_FE(min, NULL)
  110. PHP_FE(max, NULL)
  111. PHP_FE(getimagesize, NULL)
  112. PHP_FE(htmlspecialchars, NULL)
  113. PHP_FE(htmlentities, NULL)
  114. PHP_FE(md5, NULL)
  115. PHP_FE(iptcparse, NULL)
  116. PHP_FE(iptcembed, NULL)
  117. PHP_FE(phpinfo, NULL)
  118. PHP_FE(phpversion, NULL)
  119. PHP_FE(phpcredits, NULL)
  120. PHP_FE(strspn, NULL)
  121. PHP_FE(strcspn, NULL)
  122. PHP_FE(strtok, NULL)
  123. PHP_FE(strtoupper, NULL)
  124. PHP_FE(strtolower, NULL)
  125. PHP_FE(strpos, NULL)
  126. PHP_FE(strrpos, NULL)
  127. PHP_FE(strrev, NULL)
  128. PHP_FE(hebrev, NULL)
  129. PHP_FE(hebrevc, NULL)
  130. PHP_FE(nl2br, NULL)
  131. PHP_FE(basename, NULL)
  132. PHP_FE(dirname, NULL)
  133. PHP_FE(stripslashes, NULL)
  134. PHP_FE(stripcslashes, NULL)
  135. PHP_FE(strstr, NULL)
  136. PHP_FE(stristr, NULL)
  137. PHP_FE(strrchr, NULL)
  138. PHP_FE(substr, NULL)
  139. PHP_FE(quotemeta, NULL)
  140. PHP_FE(ucfirst, NULL)
  141. PHP_FE(ucwords, NULL)
  142. PHP_FE(strtr, NULL)
  143. PHP_FE(addslashes, NULL)
  144. PHP_FE(addcslashes, NULL)
  145. PHP_FE(chop, NULL)
  146. PHP_FE(str_replace, NULL)
  147. PHP_FE(chunk_split, NULL)
  148. PHP_FE(trim, NULL)
  149. PHP_FE(ltrim, NULL)
  150. PHP_FE(strip_tags, NULL)
  151. PHP_FE(similar_text, NULL)
  152. PHP_FE(explode, NULL)
  153. PHP_FE(implode, NULL)
  154. PHP_FE(setlocale, NULL)
  155. PHP_FE(soundex, NULL)
  156. PHP_FE(chr, NULL)
  157. PHP_FE(ord, NULL)
  158. PHP_FE(parse_str, NULL)
  159. PHP_FALIAS(rtrim, chop, NULL)
  160. PHP_FALIAS(strchr, strstr, NULL)
  161. PHP_NAMED_FE(sprintf, php3_user_sprintf, NULL)
  162. PHP_NAMED_FE(printf, php3_user_printf, NULL)
  163. PHP_FE(parse_url, NULL)
  164. PHP_FE(urlencode, NULL)
  165. PHP_FE(urldecode, NULL)
  166. PHP_FE(rawurlencode, NULL)
  167. PHP_FE(rawurldecode, NULL)
  168. PHP_FE(readlink, NULL)
  169. PHP_FE(linkinfo, NULL)
  170. PHP_FE(symlink, NULL)
  171. PHP_FE(link, NULL)
  172. PHP_FE(unlink, NULL)
  173. PHP_FE(exec, second_and_third_args_force_ref)
  174. PHP_FE(system, second_arg_force_ref)
  175. PHP_FE(escapeshellcmd, NULL)
  176. PHP_FE(passthru, second_arg_force_ref)
  177. PHP_FE(shell_exec, NULL)
  178. PHP_FE(rand, NULL)
  179. PHP_FE(srand, NULL)
  180. PHP_FE(getrandmax, NULL)
  181. PHP_FE(mt_rand, NULL)
  182. PHP_FE(mt_srand, NULL)
  183. PHP_FE(mt_getrandmax, NULL)
  184. PHP_FE(gethostbyaddr, NULL)
  185. PHP_FE(gethostbyname, NULL)
  186. PHP_FE(gethostbynamel, NULL)
  187. #if !(WIN32|WINNT)||HAVE_BINDLIB
  188. PHP_FE(checkdnsrr, NULL)
  189. PHP_FE(getmxrr, second_and_third_args_force_ref)
  190. #endif
  191. PHP_FE(getmyuid, NULL)
  192. PHP_FE(getmypid, NULL)
  193. PHP_FE(getmyinode, NULL)
  194. PHP_FE(getlastmod, NULL)
  195. /*getmyiid is here for forward compatibility with 3.1
  196. See pageinfo.c in 3.1 for more information*/
  197. /* {"getmyiid", php3_getmypid, NULL}, */
  198. PHP_FE(base64_decode, NULL)
  199. PHP_FE(base64_encode, NULL)
  200. PHP_FE(abs, NULL)
  201. PHP_FE(ceil, NULL)
  202. PHP_FE(floor, NULL)
  203. PHP_FE(round, NULL)
  204. PHP_FE(sin, NULL)
  205. PHP_FE(cos, NULL)
  206. PHP_FE(tan, NULL)
  207. PHP_FE(asin, NULL)
  208. PHP_FE(acos, NULL)
  209. PHP_FE(atan, NULL)
  210. PHP_FE(atan2, NULL)
  211. PHP_FE(pi, NULL)
  212. PHP_FE(pow, NULL)
  213. PHP_FE(exp, NULL)
  214. PHP_FE(log, NULL)
  215. PHP_FE(log10, NULL)
  216. PHP_FE(sqrt, NULL)
  217. PHP_FE(deg2rad, NULL)
  218. PHP_FE(rad2deg, NULL)
  219. PHP_FE(bindec, NULL)
  220. PHP_FE(hexdec, NULL)
  221. PHP_FE(octdec, NULL)
  222. PHP_FE(decbin, NULL)
  223. PHP_FE(decoct, NULL)
  224. PHP_FE(dechex, NULL)
  225. PHP_FE(base_convert, NULL)
  226. PHP_FE(number_format, NULL)
  227. PHP_FE(getenv, NULL)
  228. #ifdef HAVE_PUTENV
  229. PHP_FE(putenv, NULL)
  230. #endif
  231. PHP_FE(microtime, NULL)
  232. PHP_FE(gettimeofday, NULL)
  233. PHP_FE(getrusage, NULL)
  234. PHP_FE(uniqid, NULL)
  235. PHP_FE(quoted_printable_decode, NULL)
  236. PHP_FE(convert_cyr_string, NULL)
  237. PHP_FE(get_current_user, NULL)
  238. PHP_FE(set_time_limit, NULL)
  239. PHP_FE(get_cfg_var, NULL)
  240. PHP_FALIAS(magic_quotes_runtime, set_magic_quotes_runtime, NULL)
  241. PHP_FE(set_magic_quotes_runtime, NULL)
  242. PHP_FE(get_magic_quotes_gpc, NULL)
  243. PHP_FE(get_magic_quotes_runtime, NULL)
  244. PHP_FE(is_long, first_arg_allow_ref)
  245. PHP_FALIAS(is_int, is_long, first_arg_allow_ref)
  246. PHP_FALIAS(is_integer, is_long, first_arg_allow_ref)
  247. PHP_FALIAS(is_float, is_double, first_arg_allow_ref)
  248. PHP_FE(is_double, first_arg_allow_ref)
  249. PHP_FALIAS(is_real, is_double, first_arg_allow_ref)
  250. PHP_FE(is_string, first_arg_allow_ref)
  251. PHP_FE(is_array, first_arg_allow_ref)
  252. PHP_FE(is_object, first_arg_allow_ref)
  253. PHP_FE(error_log, NULL)
  254. PHP_FE(call_user_func, NULL)
  255. PHP_FE(call_user_method, NULL)
  256. PHP_FE(var_dump, NULL)
  257. PHP_FE(serialize, first_arg_allow_ref)
  258. PHP_FE(unserialize, first_arg_allow_ref)
  259. PHP_FE(register_shutdown_function, NULL)
  260. PHP_FE(highlight_file, NULL)
  261. PHP_NAMED_FE(show_source, php3_highlight_file, NULL)
  262. PHP_FE(highlight_string, NULL)
  263. PHP_FE(ob_start, NULL)
  264. PHP_FE(ob_end_flush, NULL)
  265. PHP_FE(ob_end_clean, NULL)
  266. PHP_FE(ob_get_contents, NULL)
  267. PHP_FE(ini_get, NULL)
  268. PHP_FE(ini_alter, NULL)
  269. PHP_FE(ini_restore, NULL)
  270. PHP_FE(print_r, NULL)
  271. PHP_FE(setcookie, NULL)
  272. PHP_NAMED_FE(header, PHP_FN(Header), NULL)
  273. PHP_FE(headers_sent, NULL)
  274. PHP_FE(function_exists, NULL)
  275. PHP_FE(in_array, NULL)
  276. PHP_FE(extract, NULL)
  277. PHP_FE(compact, NULL)
  278. PHP_FE(range, NULL)
  279. PHP_FE(array_push, first_arg_force_ref)
  280. PHP_FE(array_pop, first_arg_force_ref)
  281. PHP_FE(array_shift, first_arg_force_ref)
  282. PHP_FE(array_unshift, first_arg_force_ref)
  283. PHP_FE(array_splice, first_arg_force_ref)
  284. PHP_FE(array_slice, NULL)
  285. PHP_FE(array_merge, NULL)
  286. PHP_FE(array_keys, NULL)
  287. PHP_FE(array_values, NULL)
  288. PHP_FE(array_count_values, NULL)
  289. PHP_FE(array_reverse, NULL)
  290. PHP_FE(connection_aborted, NULL)
  291. PHP_FE(connection_timeout, NULL)
  292. PHP_FE(connection_status, NULL)
  293. PHP_FE(ignore_user_abort, NULL)
  294. {NULL, NULL, NULL}
  295. };
  296. PHP_INI_BEGIN()
  297. PHP_INI_ENTRY1("highlight.string", "#foobar", PHP_INI_ALL, NULL, NULL)
  298. PHP_INI_ENTRY1("test2", "testing", PHP_INI_SYSTEM, NULL, NULL)
  299. PHP_INI_END()
  300. php3_module_entry basic_functions_module = {
  301. "Basic Functions", /* extension name */
  302. basic_functions, /* function list */
  303. PHP_MINIT(basic), /* process startup */
  304. PHP_MSHUTDOWN(basic), /* process shutdown */
  305. PHP_RINIT(basic), /* request startup */
  306. PHP_RSHUTDOWN(basic), /* request shutdown */
  307. NULL, /* extension info */
  308. STANDARD_MODULE_PROPERTIES
  309. };
  310. #ifdef HAVE_PUTENV
  311. static HashTable putenv_ht;
  312. static int _php3_putenv_destructor(putenv_entry *pe)
  313. {
  314. if (pe->previous_value) {
  315. putenv(pe->previous_value);
  316. } else {
  317. # if HAVE_UNSETENV
  318. unsetenv(pe->key);
  319. # else
  320. char **env;
  321. for (env = environ; env != NULL && *env != NULL; env++) {
  322. if (!strncmp(*env,pe->key,pe->key_len) && (*env)[pe->key_len]=='=') { /* found it */
  323. *env = "";
  324. break;
  325. }
  326. }
  327. # endif
  328. }
  329. efree(pe->putenv_string);
  330. efree(pe->key);
  331. return 1;
  332. }
  333. #endif
  334. #ifndef M_PI
  335. #define M_PI 3.14159265358979323846
  336. #endif
  337. #define EXTR_OVERWRITE 0
  338. #define EXTR_SKIP 1
  339. #define EXTR_PREFIX_SAME 2
  340. #define EXTR_PREFIX_ALL 3
  341. void test_class_startup();
  342. PHP_MINIT_FUNCTION(basic)
  343. {
  344. ELS_FETCH();
  345. REGISTER_DOUBLE_CONSTANT("M_PI", M_PI, CONST_CS | CONST_PERSISTENT);
  346. REGISTER_LONG_CONSTANT("EXTR_OVERWRITE", EXTR_OVERWRITE, CONST_CS | CONST_PERSISTENT);
  347. REGISTER_LONG_CONSTANT("EXTR_SKIP", EXTR_SKIP, CONST_CS | CONST_PERSISTENT);
  348. REGISTER_LONG_CONSTANT("EXTR_PREFIX_SAME", EXTR_PREFIX_SAME, CONST_CS | CONST_PERSISTENT);
  349. REGISTER_LONG_CONSTANT("EXTR_PREFIX_ALL", EXTR_PREFIX_ALL, CONST_CS | CONST_PERSISTENT);
  350. test_class_startup();
  351. REGISTER_INI_ENTRIES();
  352. register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU);
  353. return SUCCESS;
  354. }
  355. PHP_MSHUTDOWN_FUNCTION(basic)
  356. {
  357. UNREGISTER_INI_ENTRIES();
  358. return SUCCESS;
  359. }
  360. PHP_RINIT_FUNCTION(basic)
  361. {
  362. strtok_string = NULL;
  363. #ifdef HAVE_PUTENV
  364. if (zend_hash_init(&putenv_ht, 1, NULL, (int (*)(void *)) _php3_putenv_destructor, 0) == FAILURE) {
  365. return FAILURE;
  366. }
  367. #endif
  368. user_compare_func_name=NULL;
  369. user_shutdown_function_names=NULL;
  370. return SUCCESS;
  371. }
  372. PHP_RSHUTDOWN_FUNCTION(basic)
  373. {
  374. STR_FREE(strtok_string);
  375. #ifdef HAVE_PUTENV
  376. zend_hash_destroy(&putenv_ht);
  377. #endif
  378. return SUCCESS;
  379. }
  380. /********************
  381. * System Functions *
  382. ********************/
  383. PHP_FUNCTION(getenv)
  384. {
  385. #if FHTTPD
  386. int i;
  387. #endif
  388. pval *str;
  389. char *ptr;
  390. SLS_FETCH();
  391. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) {
  392. WRONG_PARAM_COUNT;
  393. }
  394. convert_to_string(str);
  395. #if FHTTPD
  396. ptr=NULL;
  397. if (str->type == IS_STRING && req){
  398. for(i=0;i<req->nlines;i++){
  399. if (req->lines[i].paramc>1){
  400. if (req->lines[i].params[0]){
  401. if (!strcmp(req->lines[i].params[0],
  402. str->value.str.val)){
  403. ptr=req->lines[i].params[1];
  404. i=req->nlines;
  405. }
  406. }
  407. }
  408. }
  409. }
  410. if (!ptr) ptr = getenv(str->value.str.val);
  411. if (ptr
  412. #else
  413. if (str->type == IS_STRING &&
  414. #if APACHE
  415. ((ptr = (char *)table_get(((request_rec *) SG(server_context))->subprocess_env, str->value.str.val)) || (ptr = getenv(str->value.str.val)))
  416. #endif
  417. #if CGI_BINARY
  418. (ptr = getenv(str->value.str.val))
  419. #endif
  420. #if USE_SAPI
  421. (ptr = sapi_rqst->getenv(sapi_rqst->scid,str->value.str.val))
  422. #endif
  423. #endif
  424. ) {
  425. RETURN_STRING(ptr,1);
  426. }
  427. RETURN_FALSE;
  428. }
  429. #ifdef HAVE_PUTENV
  430. PHP_FUNCTION(putenv)
  431. {
  432. pval *str;
  433. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &str) == FAILURE) {
  434. WRONG_PARAM_COUNT;
  435. }
  436. convert_to_string(str);
  437. if (str->value.str.val && *(str->value.str.val)) {
  438. int ret;
  439. char *p,**env;
  440. putenv_entry pe;
  441. pe.putenv_string = estrndup(str->value.str.val,str->value.str.len);
  442. pe.key = str->value.str.val;
  443. if ((p=strchr(pe.key,'='))) { /* nullify the '=' if there is one */
  444. *p='\0';
  445. }
  446. pe.key_len = strlen(pe.key);
  447. pe.key = estrndup(pe.key,pe.key_len);
  448. zend_hash_del(&putenv_ht,pe.key,pe.key_len+1);
  449. /* find previous value */
  450. pe.previous_value = NULL;
  451. for (env = environ; env != NULL && *env != NULL; env++) {
  452. if (!strncmp(*env,pe.key,pe.key_len) && (*env)[pe.key_len]=='=') { /* found it */
  453. pe.previous_value = *env;
  454. break;
  455. }
  456. }
  457. if ((ret=putenv(pe.putenv_string))==0) { /* success */
  458. zend_hash_add(&putenv_ht,pe.key,pe.key_len+1,(void **) &pe,sizeof(putenv_entry),NULL);
  459. RETURN_TRUE;
  460. } else {
  461. efree(pe.putenv_string);
  462. efree(pe.key);
  463. RETURN_FALSE;
  464. }
  465. }
  466. }
  467. #endif
  468. PHP_FUNCTION(toggle_short_open_tag)
  469. {
  470. /* has to be implemented within Zend */
  471. #if 0
  472. pval *value;
  473. int ret;
  474. ret = php3_ini.short_open_tag;
  475. if (ARG_COUNT(ht)!=1 || getParameters(ht,1,&value) == FAILURE) {
  476. WRONG_PARAM_COUNT;
  477. }
  478. convert_to_long(value);
  479. php3_ini.short_open_tag = value->value.lval;
  480. RETURN_LONG(ret);
  481. #endif
  482. }
  483. /*******************
  484. * Basic Functions *
  485. *******************/
  486. PHP_FUNCTION(intval)
  487. {
  488. pval *num, *arg_base;
  489. int base;
  490. switch(ARG_COUNT(ht)) {
  491. case 1:
  492. if (getParameters(ht, 1, &num) == FAILURE) {
  493. WRONG_PARAM_COUNT;
  494. }
  495. base = 10;
  496. break;
  497. case 2:
  498. if (getParameters(ht, 2, &num, &arg_base) == FAILURE) {
  499. WRONG_PARAM_COUNT;
  500. }
  501. convert_to_long(arg_base);
  502. base = arg_base->value.lval;
  503. break;
  504. default:
  505. WRONG_PARAM_COUNT;
  506. }
  507. convert_to_long_base(num, base);
  508. *return_value = *num;
  509. }
  510. PHP_FUNCTION(doubleval)
  511. {
  512. pval *num;
  513. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) {
  514. WRONG_PARAM_COUNT;
  515. }
  516. convert_to_double(num);
  517. *return_value = *num;
  518. }
  519. PHP_FUNCTION(strval)
  520. {
  521. pval *num;
  522. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) {
  523. WRONG_PARAM_COUNT;
  524. }
  525. convert_to_string(num);
  526. *return_value = *num;
  527. pval_copy_constructor(return_value);
  528. }
  529. static int array_key_compare(const void *a, const void *b)
  530. {
  531. Bucket *first;
  532. Bucket *second;
  533. int min, r;
  534. first = *((Bucket **) a);
  535. second = *((Bucket **) b);
  536. if (first->nKeyLength == 0 && second->nKeyLength == 0) {
  537. return (first->h - second->h);
  538. } else if (first->nKeyLength == 0) {
  539. return -1;
  540. } else if (second->nKeyLength == 0) {
  541. return 1;
  542. }
  543. min = MIN(first->nKeyLength, second->nKeyLength);
  544. if ((r = memcmp(first->arKey, second->arKey, min)) == 0) {
  545. return (first->nKeyLength - second->nKeyLength);
  546. } else {
  547. return r;
  548. }
  549. }
  550. static int array_reverse_key_compare(const void *a, const void *b)
  551. {
  552. return array_key_compare(a,b)*-1;
  553. }
  554. PHP_FUNCTION(krsort)
  555. {
  556. pval *array;
  557. HashTable *target_hash;
  558. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  559. WRONG_PARAM_COUNT;
  560. }
  561. target_hash = HASH_OF(array);
  562. if (!target_hash) {
  563. php_error(E_WARNING, "Wrong datatype in krsort() call");
  564. return;
  565. }
  566. if (!ParameterPassedByReference(ht,1)) {
  567. php_error(E_WARNING, "Array not passed by reference in call to krsort()");
  568. return;
  569. }
  570. if (zend_hash_sort(target_hash, array_reverse_key_compare,0) == FAILURE) {
  571. return;
  572. }
  573. RETURN_TRUE;
  574. }
  575. PHP_FUNCTION(ksort)
  576. {
  577. pval *array;
  578. HashTable *target_hash;
  579. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  580. WRONG_PARAM_COUNT;
  581. }
  582. target_hash = HASH_OF(array);
  583. if (!target_hash) {
  584. php_error(E_WARNING, "Wrong datatype in ksort() call");
  585. return;
  586. }
  587. if (!ParameterPassedByReference(ht,1)) {
  588. php_error(E_WARNING, "Array not passed by reference in call to ksort()");
  589. return;
  590. }
  591. if (zend_hash_sort(target_hash, array_key_compare,0) == FAILURE) {
  592. return;
  593. }
  594. RETURN_TRUE;
  595. }
  596. PHP_FUNCTION(count)
  597. {
  598. pval **array;
  599. HashTable *target_hash;
  600. if (ARG_COUNT(ht) != 1 || getParametersEx(1, &array) == FAILURE) {
  601. WRONG_PARAM_COUNT;
  602. }
  603. target_hash = HASH_OF(*array);
  604. if (!target_hash) {
  605. if ((*array)->type == IS_STRING && (*array)->value.str.val==undefined_variable_string) {
  606. RETURN_LONG(0);
  607. } else {
  608. RETURN_LONG(1);
  609. }
  610. }
  611. RETURN_LONG(zend_hash_num_elements(target_hash));
  612. }
  613. /* Numbers are always smaller than strings int this function as it
  614. * anyway doesn't make much sense to compare two different data types.
  615. * This keeps it consistant and simple.
  616. */
  617. static int array_data_compare(const void *a, const void *b)
  618. {
  619. Bucket *f;
  620. Bucket *s;
  621. pval *first;
  622. pval *second;
  623. double dfirst, dsecond;
  624. f = *((Bucket **) a);
  625. s = *((Bucket **) b);
  626. first = *((pval **) f->pData);
  627. second = *((pval **) s->pData);
  628. if ((first->type == IS_LONG || first->type == IS_DOUBLE) &&
  629. (second->type == IS_LONG || second->type == IS_DOUBLE)) {
  630. if (first->type == IS_LONG) {
  631. dfirst = (double) first->value.lval;
  632. } else {
  633. dfirst = first->value.dval;
  634. }
  635. if (second->type == IS_LONG) {
  636. dsecond = (double) second->value.lval;
  637. } else {
  638. dsecond = second->value.dval;
  639. }
  640. if (dfirst < dsecond) {
  641. return -1;
  642. } else if (dfirst == dsecond) {
  643. return 0;
  644. } else {
  645. return 1;
  646. }
  647. }
  648. if ((first->type == IS_LONG || first->type == IS_DOUBLE) &&
  649. second->type == IS_STRING) {
  650. return -1;
  651. } else if ((first->type == IS_STRING) &&
  652. (second->type == IS_LONG || second->type == IS_DOUBLE)) {
  653. return 1;
  654. }
  655. if (first->type == IS_STRING && second->type == IS_STRING) {
  656. return strcmp(first->value.str.val, second->value.str.val);
  657. }
  658. return 0; /* Anything else is equal as it can't be compared */
  659. }
  660. static int array_reverse_data_compare(const void *a, const void *b)
  661. {
  662. return array_data_compare(a,b)*-1;
  663. }
  664. PHP_FUNCTION(asort)
  665. {
  666. pval *array;
  667. HashTable *target_hash;
  668. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  669. WRONG_PARAM_COUNT;
  670. }
  671. target_hash = HASH_OF(array);
  672. if (!target_hash) {
  673. php_error(E_WARNING, "Wrong datatype in asort() call");
  674. return;
  675. }
  676. if (!ParameterPassedByReference(ht,1)) {
  677. php_error(E_WARNING, "Array not passed by reference in call to asort()");
  678. return;
  679. }
  680. if (zend_hash_sort(target_hash, array_data_compare,0) == FAILURE) {
  681. return;
  682. }
  683. RETURN_TRUE;
  684. }
  685. PHP_FUNCTION(arsort)
  686. {
  687. pval *array;
  688. HashTable *target_hash;
  689. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  690. WRONG_PARAM_COUNT;
  691. }
  692. target_hash = HASH_OF(array);
  693. if (!target_hash) {
  694. php_error(E_WARNING, "Wrong datatype in arsort() call");
  695. return;
  696. }
  697. if (!ParameterPassedByReference(ht,1)) {
  698. php_error(E_WARNING, "Array not passed by reference in call to arsort()");
  699. return;
  700. }
  701. if (zend_hash_sort(target_hash, array_reverse_data_compare,0) == FAILURE) {
  702. return;
  703. }
  704. RETURN_TRUE;
  705. }
  706. PHP_FUNCTION(sort)
  707. {
  708. pval *array;
  709. HashTable *target_hash;
  710. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  711. WRONG_PARAM_COUNT;
  712. }
  713. target_hash = HASH_OF(array);
  714. if (!target_hash) {
  715. php_error(E_WARNING, "Wrong datatype in sort() call");
  716. return;
  717. }
  718. if (!ParameterPassedByReference(ht,1)) {
  719. php_error(E_WARNING, "Array not passed by reference in call to sort()");
  720. return;
  721. }
  722. if (zend_hash_sort(target_hash, array_data_compare,1) == FAILURE) {
  723. return;
  724. }
  725. RETURN_TRUE;
  726. }
  727. PHP_FUNCTION(rsort)
  728. {
  729. pval *array;
  730. HashTable *target_hash;
  731. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  732. WRONG_PARAM_COUNT;
  733. }
  734. target_hash = HASH_OF(array);
  735. if (!target_hash) {
  736. php_error(E_WARNING, "Wrong datatype in rsort() call");
  737. return;
  738. }
  739. if (!ParameterPassedByReference(ht,1)) {
  740. php_error(E_WARNING, "Array not passed by reference in call to rsort()");
  741. return;
  742. }
  743. if (zend_hash_sort(target_hash, array_reverse_data_compare,1) == FAILURE) {
  744. return;
  745. }
  746. RETURN_TRUE;
  747. }
  748. static int array_user_compare(const void *a, const void *b)
  749. {
  750. Bucket *f;
  751. Bucket *s;
  752. pval **args[2];
  753. pval retval;
  754. CLS_FETCH();
  755. f = *((Bucket **) a);
  756. s = *((Bucket **) b);
  757. args[0] = (pval **) f->pData;
  758. args[1] = (pval **) s->pData;
  759. if (call_user_function_ex(CG(function_table), NULL, user_compare_func_name, &retval, 2, args, 0)==SUCCESS) {
  760. convert_to_long(&retval);
  761. return retval.value.lval;
  762. } else {
  763. return 0;
  764. }
  765. }
  766. PHP_FUNCTION(usort)
  767. {
  768. pval *array;
  769. pval *old_compare_func;
  770. HashTable *target_hash;
  771. old_compare_func = user_compare_func_name;
  772. if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &user_compare_func_name) == FAILURE) {
  773. user_compare_func_name = old_compare_func;
  774. WRONG_PARAM_COUNT;
  775. }
  776. target_hash = HASH_OF(array);
  777. if (!target_hash) {
  778. php_error(E_WARNING, "Wrong datatype in usort() call");
  779. user_compare_func_name = old_compare_func;
  780. return;
  781. }
  782. convert_to_string(user_compare_func_name);
  783. if (zend_hash_sort(target_hash, array_user_compare, 1) == FAILURE) {
  784. user_compare_func_name = old_compare_func;
  785. return;
  786. }
  787. user_compare_func_name = old_compare_func;
  788. RETURN_TRUE;
  789. }
  790. PHP_FUNCTION(uasort)
  791. {
  792. pval *array;
  793. pval *old_compare_func;
  794. HashTable *target_hash;
  795. old_compare_func = user_compare_func_name;
  796. if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &user_compare_func_name) == FAILURE) {
  797. user_compare_func_name = old_compare_func;
  798. WRONG_PARAM_COUNT;
  799. }
  800. target_hash = HASH_OF(array);
  801. if (!target_hash) {
  802. php_error(E_WARNING, "Wrong datatype in uasort() call");
  803. user_compare_func_name = old_compare_func;
  804. return;
  805. }
  806. convert_to_string(user_compare_func_name);
  807. if (zend_hash_sort(target_hash, array_user_compare, 0) == FAILURE) {
  808. user_compare_func_name = old_compare_func;
  809. return;
  810. }
  811. user_compare_func_name = old_compare_func;
  812. RETURN_TRUE;
  813. }
  814. static int array_user_key_compare(const void *a, const void *b)
  815. {
  816. Bucket *f;
  817. Bucket *s;
  818. pval key1, key2;
  819. pval *args[2];
  820. pval retval;
  821. int status;
  822. CLS_FETCH();
  823. args[0] = &key1;
  824. args[1] = &key2;
  825. INIT_PZVAL(&key1);
  826. INIT_PZVAL(&key2);
  827. f = *((Bucket **) a);
  828. s = *((Bucket **) b);
  829. if (f->nKeyLength) {
  830. key1.value.str.val = estrndup(f->arKey, f->nKeyLength);
  831. key1.value.str.len = f->nKeyLength;
  832. key1.type = IS_STRING;
  833. } else {
  834. key1.value.lval = f->h;
  835. key1.type = IS_LONG;
  836. }
  837. if (s->nKeyLength) {
  838. key2.value.str.val = estrndup(s->arKey, s->nKeyLength);
  839. key2.value.str.len = s->nKeyLength;
  840. key2.type = IS_STRING;
  841. } else {
  842. key2.value.lval = s->h;
  843. key2.type = IS_LONG;
  844. }
  845. status = call_user_function(CG(function_table), NULL, user_compare_func_name, &retval, 2, args);
  846. pval_destructor(&key1);
  847. pval_destructor(&key2);
  848. if (status==SUCCESS) {
  849. convert_to_long(&retval);
  850. return retval.value.lval;
  851. } else {
  852. return 0;
  853. }
  854. }
  855. PHP_FUNCTION(uksort)
  856. {
  857. pval *array;
  858. pval *old_compare_func;
  859. HashTable *target_hash;
  860. old_compare_func = user_compare_func_name;
  861. if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &array, &user_compare_func_name) == FAILURE) {
  862. user_compare_func_name = old_compare_func;
  863. WRONG_PARAM_COUNT;
  864. }
  865. target_hash = HASH_OF(array);
  866. if (!target_hash) {
  867. php_error(E_WARNING, "Wrong datatype in uksort() call");
  868. user_compare_func_name = old_compare_func;
  869. return;
  870. }
  871. convert_to_string(user_compare_func_name);
  872. if (zend_hash_sort(target_hash, array_user_key_compare, 0) == FAILURE) {
  873. user_compare_func_name = old_compare_func;
  874. return;
  875. }
  876. user_compare_func_name = old_compare_func;
  877. RETURN_TRUE;
  878. }
  879. PHP_FUNCTION(end)
  880. {
  881. pval *array, **entry;
  882. HashTable *target_hash;
  883. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  884. WRONG_PARAM_COUNT;
  885. }
  886. target_hash = HASH_OF(array);
  887. if (!target_hash) {
  888. php_error(E_WARNING, "Variable passed to end() is not an array or object");
  889. return;
  890. }
  891. if (!ParameterPassedByReference(ht,1)) {
  892. php_error(E_WARNING, "Array not passed by reference in call to end()");
  893. }
  894. zend_hash_internal_pointer_end(target_hash);
  895. if (zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) {
  896. RETURN_FALSE;
  897. }
  898. *return_value = **entry;
  899. pval_copy_constructor(return_value);
  900. }
  901. PHP_FUNCTION(prev)
  902. {
  903. pval *array, **entry;
  904. HashTable *target_hash;
  905. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  906. WRONG_PARAM_COUNT;
  907. }
  908. target_hash = HASH_OF(array);
  909. if (!target_hash) {
  910. php_error(E_WARNING, "Variable passed to prev() is not an array or object");
  911. RETURN_FALSE;
  912. }
  913. zend_hash_move_backwards(target_hash);
  914. if (zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) {
  915. RETURN_FALSE;
  916. }
  917. *return_value = **entry;
  918. pval_copy_constructor(return_value);
  919. }
  920. PHP_FUNCTION(next)
  921. {
  922. pval *array, **entry;
  923. HashTable *target_hash;
  924. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  925. WRONG_PARAM_COUNT;
  926. }
  927. target_hash = HASH_OF(array);
  928. if (!target_hash) {
  929. php_error(E_WARNING, "Variable passed to next() is not an array or object");
  930. RETURN_FALSE;
  931. }
  932. zend_hash_move_forward(target_hash);
  933. if (zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) {
  934. RETURN_FALSE;
  935. }
  936. *return_value = **entry;
  937. pval_copy_constructor(return_value);
  938. }
  939. PHP_FUNCTION(reset)
  940. {
  941. pval *array, **entry;
  942. HashTable *target_hash;
  943. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  944. WRONG_PARAM_COUNT;
  945. }
  946. target_hash = HASH_OF(array);
  947. if (!target_hash) {
  948. php_error(E_WARNING, "Variable passed to reset() is not an array or object");
  949. return;
  950. }
  951. zend_hash_internal_pointer_reset(target_hash);
  952. if (zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) {
  953. return;
  954. }
  955. *return_value = **entry;
  956. pval_copy_constructor(return_value);
  957. INIT_PZVAL(return_value);
  958. }
  959. PHP_FUNCTION(current)
  960. {
  961. pval *array, **entry;
  962. HashTable *target_hash;
  963. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  964. WRONG_PARAM_COUNT;
  965. }
  966. target_hash = HASH_OF(array);
  967. if (!target_hash) {
  968. php_error(E_WARNING, "Variable passed to current() is not an array or object");
  969. return;
  970. }
  971. if (zend_hash_get_current_data(target_hash, (void **) &entry) == FAILURE) {
  972. return;
  973. }
  974. *return_value = **entry;
  975. pval_copy_constructor(return_value);
  976. }
  977. PHP_FUNCTION(key)
  978. {
  979. pval *array;
  980. char *string_key;
  981. ulong num_key;
  982. HashTable *target_hash;
  983. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &array) == FAILURE) {
  984. WRONG_PARAM_COUNT;
  985. }
  986. target_hash = HASH_OF(array);
  987. if (!target_hash) {
  988. php_error(E_WARNING, "Variable passed to key() is not an array or object");
  989. return;
  990. }
  991. if (!ParameterPassedByReference(ht,1)) {
  992. php_error(E_WARNING, "Array not passed by reference in call to key()");
  993. }
  994. switch (zend_hash_get_current_key(target_hash, &string_key, &num_key)) {
  995. case HASH_KEY_IS_STRING:
  996. return_value->value.str.val = string_key;
  997. return_value->value.str.len = strlen(string_key);
  998. return_value->type = IS_STRING;
  999. break;
  1000. case HASH_KEY_IS_LONG:
  1001. return_value->type = IS_LONG;
  1002. return_value->value.lval = num_key;
  1003. break;
  1004. case HASH_KEY_NON_EXISTANT:
  1005. return;
  1006. }
  1007. }
  1008. #ifdef __cplusplus
  1009. void php3_flush(HashTable *)
  1010. #else
  1011. PHP_FUNCTION(flush)
  1012. #endif
  1013. {
  1014. SLS_FETCH();
  1015. #if APACHE
  1016. # if MODULE_MAGIC_NUMBER > 19970110
  1017. rflush(((request_rec *) SG(server_context)));
  1018. # else
  1019. bflush(((request_rec *) SG(server_context))->connection->client);
  1020. # endif
  1021. #endif
  1022. #if FHTTPD
  1023. /*FIXME -- what does it flush really? the whole response?*/
  1024. #endif
  1025. #if CGI_BINARY
  1026. fflush(stdout);
  1027. #endif
  1028. #if USE_SAPI
  1029. sapi_rqst->flush(sapi_rqst->scid);
  1030. #endif
  1031. }
  1032. PHP_FUNCTION(sleep)
  1033. {
  1034. pval *num;
  1035. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) {
  1036. WRONG_PARAM_COUNT;
  1037. }
  1038. convert_to_long(num);
  1039. sleep(num->value.lval);
  1040. }
  1041. PHP_FUNCTION(usleep)
  1042. {
  1043. #if HAVE_USLEEP
  1044. pval *num;
  1045. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &num) == FAILURE) {
  1046. WRONG_PARAM_COUNT;
  1047. }
  1048. convert_to_long(num);
  1049. usleep(num->value.lval);
  1050. #endif
  1051. }
  1052. PHP_FUNCTION(gettype)
  1053. {
  1054. pval *arg;
  1055. if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) {
  1056. WRONG_PARAM_COUNT;
  1057. }
  1058. switch (arg->type) {
  1059. case IS_BOOL:
  1060. RETVAL_STRING("boolean",1);
  1061. break;
  1062. case IS_LONG:
  1063. RETVAL_STRING("integer",1);
  1064. break;
  1065. case IS_RESOURCE:
  1066. RETVAL_STRING("resource",1);
  1067. break;
  1068. case IS_DOUBLE:
  1069. RETVAL_STRING("double",1);
  1070. break;
  1071. case IS_STRING:
  1072. RETVAL_STRING("string",1);
  1073. break;
  1074. case IS_ARRAY:
  1075. RETVAL_STRING("array",1);
  1076. break;
  1077. case IS_OBJECT:
  1078. RETVAL_STRING("object",1);
  1079. break;
  1080. /*
  1081. {
  1082. char *result;
  1083. int res_len;
  1084. res_len = sizeof("object of type ")-1 + arg->value.obj.ce->name_length;
  1085. result = (char *) emalloc(res_len+1);
  1086. sprintf(result, "object of type %s", arg->value.obj.ce->name);
  1087. RETVAL_STRINGL(result, res_len, 0);
  1088. }
  1089. */
  1090. break;
  1091. default:
  1092. RETVAL_STRING("unknown type",1);
  1093. }
  1094. }
  1095. PHP_FUNCTION(settype)
  1096. {
  1097. pval *var, *type;
  1098. char *new_type;
  1099. if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &var, &type) ==
  1100. FAILURE) {
  1101. WRONG_PARAM_COUNT;
  1102. }
  1103. convert_to_string(type);
  1104. new_type = type->value.str.val;
  1105. if (!strcasecmp(new_type, "integer")) {
  1106. convert_to_long(var);
  1107. } else if (!strcasecmp(new_type, "double")) {
  1108. convert_to_double(var);
  1109. } else if (!strcasecmp(new_type, "string")) {
  1110. convert_to_string(var);
  1111. } else if (!strcasecmp(new_type, "array")) {
  1112. convert_to_array(var);
  1113. } else if (!strcasecmp(new_type, "object")) {
  1114. convert_to_object(var);
  1115. } else if (!strcasecmp(new_type, "boolean")) {
  1116. convert_to_boolean(var);
  1117. } else if (!strcasecmp(new_type, "resource")) {
  1118. php_error(E_WARNING, "settype: cannot convert to resource type");
  1119. RETURN_FALSE;
  1120. } else {
  1121. php_error(E_WARNING, "settype: invalid type");
  1122. RETURN_FALSE;
  1123. }
  1124. RETVAL_TRUE;
  1125. }
  1126. PHP_FUNCTION(min)
  1127. {
  1128. int argc=ARG_COUNT(ht);
  1129. pval **result;
  1130. if (argc<=0) {
  1131. php_error(E_WARNING, "min: must be passed at least 1 value");
  1132. var_uninit(return_value);
  1133. return;
  1134. }
  1135. if (argc == 1) {
  1136. pval *arr;
  1137. if (getParameters(ht, 1, &arr) == FAILURE ||
  1138. arr->type != IS_ARRAY) {
  1139. WRONG_PARAM_COUNT;
  1140. }
  1141. if (zend_hash_minmax(arr->value.ht, array_data_compare, 0, (void **) &result)==SUCCESS) {
  1142. *return_value = **result;
  1143. pval_copy_constructor(return_value);
  1144. } else {
  1145. php_error(E_WARNING, "min: array must contain at least 1 element");
  1146. var_uninit(return_value);
  1147. }
  1148. } else {
  1149. pval **args = (pval **) emalloc(sizeof(pval *)*ARG_COUNT(ht));
  1150. pval *min, result;
  1151. int i;
  1152. if (getParametersArray(ht, ARG_COUNT(ht), args)==FAILURE) {
  1153. efree(args);
  1154. WRONG_PARAM_COUNT;
  1155. }
  1156. min = args[0];
  1157. for (i=1; i<ARG_COUNT(ht); i++) {
  1158. is_smaller_function(&result, args[i], min);
  1159. if (result.value.lval == 1) {
  1160. min = args[i];
  1161. }
  1162. }
  1163. *return_value = *min;
  1164. pval_copy_constructor(return_value);
  1165. efree(args);
  1166. }
  1167. }
  1168. PHP_FUNCTION(max)
  1169. {
  1170. int argc=ARG_COUNT(ht);
  1171. pval **result;
  1172. if (argc<=0) {
  1173. php_error(E_WARNING, "max: must be passed at least 1 value");
  1174. var_uninit(return_value);
  1175. return;
  1176. }
  1177. if (argc == 1) {
  1178. pval *arr;
  1179. if (getParameters(ht, 1, &arr) == FAILURE ||
  1180. arr->type != IS_ARRAY) {
  1181. WRONG_PARAM_COUNT;
  1182. }
  1183. if (zend_hash_minmax(arr->value.ht, array_data_compare, 1, (void **) &result)==SUCCESS) {
  1184. *return_value = **result;
  1185. pval_copy_constructor(return_value);
  1186. } else {
  1187. php_error(E_WARNING, "max: array must contain at least 1 element");
  1188. var_uninit(return_value);
  1189. }
  1190. } else {
  1191. pval **args = (pval **) emalloc(sizeof(pval *)*ARG_COUNT(ht));
  1192. pval *max, result;
  1193. int i;
  1194. if (getParametersArray(ht, ARG_COUNT(ht), args)==FAILURE) {
  1195. efree(args);
  1196. WRONG_PARAM_COUNT;
  1197. }
  1198. max = args[0];
  1199. for (i=1; i<ARG_COUNT(ht); i++) {
  1200. is_smaller_or_equal_function(&result, args[i], max);
  1201. if (result.value.lval == 0) {
  1202. max = args[i];
  1203. }
  1204. }
  1205. *return_value = *max;
  1206. pval_copy_constructor(return_value);
  1207. efree(args);
  1208. }
  1209. }
  1210. static zval **php_array_walk_func_name;
  1211. static int php_array_walk(HashTable *target_hash, zval **userdata)
  1212. {
  1213. zval **args[3], /* Arguments to userland function */
  1214. retval, /* Return value - unused */
  1215. *key; /* Entry key */
  1216. char *string_key;
  1217. ulong num_key;
  1218. CLS_FETCH();
  1219. /* Allocate space for key */
  1220. MAKE_STD_ZVAL(key);
  1221. /* Set up known arguments */
  1222. args[1] = &key;
  1223. args[2] = userdata;
  1224. /* Iterate through hash */
  1225. while(zend_hash_get_current_data(target_hash, (void **)&args[0]) == SUCCESS) {
  1226. /* Set up the key */
  1227. if (zend_hash_get_current_key(target_hash, &string_key, &num_key) == HASH_KEY_IS_LONG) {
  1228. key->type = IS_LONG;
  1229. key->value.lval = num_key;
  1230. } else {
  1231. key->type = IS_STRING;
  1232. key->value.str.val = string_key;
  1233. key->value.str.len = strlen(string_key);
  1234. }
  1235. /* Call the userland function */
  1236. call_user_function_ex(CG(function_table), NULL, *php_array_walk_func_name,
  1237. &retval, userdata ? 3 : 2, args, 0);
  1238. /* Clean up the key */
  1239. if (zend_hash_get_current_key_type(target_hash) == HASH_KEY_IS_STRING)
  1240. efree(key->value.str.val);
  1241. zend_hash_move_forward(target_hash);
  1242. }
  1243. efree(key);
  1244. return 0;
  1245. }
  1246. /* {{{ proto array_walk(array input, string funcname [, mixed userdata])
  1247. Apply a user function to every member of an array */
  1248. PHP_FUNCTION(array_walk) {
  1249. int argc;
  1250. zval **array,
  1251. **userdata = NULL,
  1252. **old_walk_func_name;
  1253. HashTable *target_hash;
  1254. argc = ARG_COUNT(ht);
  1255. old_walk_func_name = php_array_walk_func_name;
  1256. if (argc < 2 || argc > 3 ||
  1257. getParametersEx(argc, &array, &php_array_walk_func_name, &userdata) == FAILURE) {
  1258. php_array_walk_func_name = old_walk_func_name;
  1259. WRONG_PARAM_COUNT;
  1260. }
  1261. target_hash = HASH_OF(*array);
  1262. if (!target_hash) {
  1263. php_error(E_WARNING, "Wrong datatype in array_walk() call");
  1264. php_array_walk_func_name = old_walk_func_name;
  1265. return;
  1266. }
  1267. convert_to_string_ex(php_array_walk_func_name);
  1268. php_array_walk(target_hash, userdata);
  1269. php_array_walk_func_name = old_walk_func_name;
  1270. RETURN_TRUE;
  1271. }
  1272. #if 0
  1273. PHP_FUNCTION(max)
  1274. {
  1275. pval **argv;
  1276. int argc, i;
  1277. unsigned short max_type = IS_LONG;
  1278. argc = ARG_COUNT(ht);
  1279. /* if there is one parameter and this parameter is an array of
  1280. * 2 or more elements, use that array
  1281. */
  1282. if (argc == 1) {
  1283. argv = (pval **)emalloc(sizeof(pval *) * argc);
  1284. if (getParametersArray(ht, argc, argv) == FAILURE ||
  1285. argv[0]->type != IS_ARRAY) {
  1286. WRONG_PARAM_COUNT;
  1287. }
  1288. if (argv[0]->value.ht->nNumOfElements < 2) {
  1289. php_error(E_WARNING,
  1290. "min: array must contain at least 2 elements");
  1291. RETURN_FALSE;
  1292. }
  1293. /* replace the function parameters with the array */
  1294. ht = argv[0]->value.ht;
  1295. argc = zend_hash_num_elements(ht);
  1296. efree(argv);
  1297. } else if (argc < 2) {
  1298. WRONG_PARAM_COUNT;
  1299. }
  1300. argv = (pval **)emalloc(sizeof(pval *) * argc);
  1301. if (getParametersArray(ht, argc, argv) == FAILURE) {
  1302. efree(argv);
  1303. WRONG_PARAM_COUNT;
  1304. }
  1305. /* figure out what types to compare
  1306. * if the arguments contain a double, convert all of them to a double
  1307. * else convert all of them to long
  1308. */
  1309. for (i = 0; i < argc; i++) {
  1310. if (argv[i]->type == IS_DOUBLE) {
  1311. max_type = IS_DOUBLE;
  1312. break;
  1313. }
  1314. }
  1315. if (max_type == IS_LONG) {
  1316. convert_to_long(argv[0]);
  1317. return_value->value.lval = argv[0]->value.lval;
  1318. for (i = 1; i < argc; i++) {
  1319. convert_to_long(argv[i]);
  1320. if (argv[i]->value.lval > return_value->value.lval) {
  1321. return_value->value.lval = argv[i]->value.lval;
  1322. }
  1323. }
  1324. } else {
  1325. convert_to_double(argv[0]);
  1326. return_value->value.dval = argv[0]->value.dval;
  1327. for (i = 1; i < argc; i++) {
  1328. convert_to_double(argv[i]);
  1329. if (argv[i]->value.dval > return_value->value.dval) {
  1330. return_value->value.dval = argv[i]->value.dval;
  1331. }
  1332. }
  1333. }
  1334. efree(argv);
  1335. return_value->type = max_type;
  1336. }
  1337. #endif
  1338. PHP_FUNCTION(get_current_user)
  1339. {
  1340. RETURN_STRING(_php3_get_current_user(),1);
  1341. }
  1342. PHP_FUNCTION(get_cfg_var)
  1343. {
  1344. pval *varname;
  1345. char *value;
  1346. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &varname)==FAILURE) {
  1347. WRONG_PARAM_COUNT;
  1348. }
  1349. convert_to_string(varname);
  1350. if (cfg_get_string(varname->value.str.val,&value)==FAILURE) {
  1351. RETURN_FALSE;
  1352. }
  1353. RETURN_STRING(value,1);
  1354. }
  1355. PHP_FUNCTION(set_magic_quotes_runtime)
  1356. {
  1357. pval *new_setting;
  1358. PLS_FETCH();
  1359. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &new_setting)==FAILURE) {
  1360. RETURN_FALSE;
  1361. }
  1362. convert_to_boolean(new_setting);
  1363. PG(magic_quotes_runtime) = (zend_bool) new_setting->value.lval;
  1364. RETURN_TRUE;
  1365. }
  1366. PHP_FUNCTION(get_magic_quotes_runtime)
  1367. {
  1368. PLS_FETCH();
  1369. RETURN_LONG(PG(magic_quotes_runtime));
  1370. }
  1371. PHP_FUNCTION(get_magic_quotes_gpc)
  1372. {
  1373. PLS_FETCH();
  1374. RETURN_LONG(PG(magic_quotes_gpc));
  1375. }
  1376. void php3_is_type(INTERNAL_FUNCTION_PARAMETERS,int type)
  1377. {
  1378. pval **arg;
  1379. if (ARG_COUNT(ht)!=1 || getParametersEx(1, &arg)==FAILURE) {
  1380. RETURN_FALSE;
  1381. }
  1382. if ((*arg)->type == type) {
  1383. RETURN_TRUE;
  1384. } else {
  1385. RETURN_FALSE;
  1386. }
  1387. }
  1388. PHP_FUNCTION(is_long)
  1389. {
  1390. php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
  1391. }
  1392. PHP_FUNCTION(is_double)
  1393. {
  1394. php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
  1395. }
  1396. PHP_FUNCTION(is_string)
  1397. {
  1398. php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
  1399. }
  1400. PHP_FUNCTION(is_array)
  1401. {
  1402. php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
  1403. }
  1404. PHP_FUNCTION(is_object)
  1405. {
  1406. php3_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
  1407. }
  1408. /*
  1409. 1st arg = error message
  1410. 2nd arg = error option
  1411. 3rd arg = optional parameters (email address or tcp address)
  1412. 4th arg = used for additional headers if email
  1413. error options
  1414. 0 = send to php_error_log (uses syslog or file depending on ini setting)
  1415. 1 = send via email to 3rd parameter 4th option = additional headers
  1416. 2 = send via tcp/ip to 3rd parameter (name or ip:port)
  1417. 3 = save to file in 3rd parameter
  1418. */
  1419. PHP_FUNCTION(error_log)
  1420. {
  1421. pval *string, *erropt = NULL, *option = NULL, *emailhead = NULL;
  1422. int opt_err = 0;
  1423. char *message, *opt=NULL, *headers=NULL;
  1424. switch(ARG_COUNT(ht)) {
  1425. case 1:
  1426. if (getParameters(ht,1,&string) == FAILURE) {
  1427. php_error(E_WARNING,"Invalid argument 1 in error_log");
  1428. RETURN_FALSE;
  1429. }
  1430. break;
  1431. case 2:
  1432. if (getParameters(ht,2,&string,&erropt) == FAILURE) {
  1433. php_error(E_WARNING,"Invalid arguments in error_log");
  1434. RETURN_FALSE;
  1435. }
  1436. convert_to_long(erropt);
  1437. opt_err=erropt->value.lval;
  1438. break;
  1439. case 3:
  1440. if (getParameters(ht,3,&string,&erropt,&option) == FAILURE){
  1441. php_error(E_WARNING,"Invalid arguments in error_log");
  1442. RETURN_FALSE;
  1443. }
  1444. convert_to_long(erropt);
  1445. opt_err=erropt->value.lval;
  1446. convert_to_string(option);
  1447. opt=option->value.str.val;
  1448. break;
  1449. case 4:
  1450. if (getParameters(ht,4,&string,&erropt,&option,&emailhead) == FAILURE){
  1451. php_error(E_WARNING,"Invalid arguments in error_log");
  1452. RETURN_FALSE;
  1453. }
  1454. break;
  1455. default:
  1456. WRONG_PARAM_COUNT;
  1457. }
  1458. convert_to_string(string);
  1459. message=string->value.str.val;
  1460. if (erropt != NULL) {
  1461. convert_to_long(erropt);
  1462. opt_err=erropt->value.lval;
  1463. }
  1464. if (option != NULL) {
  1465. convert_to_string(option);
  1466. opt=option->value.str.val;
  1467. }
  1468. if (emailhead != NULL) {
  1469. convert_to_string(emailhead);
  1470. headers=emailhead->value.str.val;
  1471. }
  1472. if (_php_error_log(opt_err,message,opt,headers)==FAILURE) {
  1473. RETURN_FALSE;
  1474. }
  1475. RETURN_TRUE;
  1476. }
  1477. PHPAPI int _php_error_log(int opt_err,char *message,char *opt,char *headers){
  1478. FILE *logfile;
  1479. int issock=0, socketd=0;;
  1480. switch(opt_err){
  1481. case 1: /*send an email*/
  1482. {
  1483. #if HAVE_SENDMAIL
  1484. if (!_php3_mail(opt,"PHP3 error_log message",message,headers)){
  1485. return FAILURE;
  1486. }
  1487. #else
  1488. php_error(E_WARNING,"Mail option not available!");
  1489. return FAILURE;
  1490. #endif
  1491. }
  1492. break;
  1493. case 2: /*send to an address */
  1494. php_error(E_WARNING,"TCP/IP option not available!");
  1495. return FAILURE;
  1496. break;
  1497. case 3: /*save to a file*/
  1498. logfile=php3_fopen_wrapper(opt,"a", (IGNORE_URL|ENFORCE_SAFE_MODE), &issock, &socketd);
  1499. if(!logfile) {
  1500. php_error(E_WARNING,"error_log: Unable to write to %s",opt);
  1501. return FAILURE;
  1502. }
  1503. fwrite(message,strlen(message),1,logfile);
  1504. fclose(logfile);
  1505. break;
  1506. default:
  1507. php3_log_err(message);
  1508. break;
  1509. }
  1510. return SUCCESS;
  1511. }
  1512. PHP_FUNCTION(call_user_func)
  1513. {
  1514. pval ***params;
  1515. pval retval;
  1516. int arg_count=ARG_COUNT(ht);
  1517. CLS_FETCH();
  1518. if (arg_count<1) {
  1519. WRONG_PARAM_COUNT;
  1520. }
  1521. params = (pval ***) emalloc(sizeof(pval **)*arg_count);
  1522. if (getParametersArrayEx(arg_count, params)==FAILURE) {
  1523. efree(params);
  1524. RETURN_FALSE;
  1525. }
  1526. SEPARATE_ZVAL(params[0]);
  1527. convert_to_string(*params[0]);
  1528. if (call_user_function_ex(CG(function_table), NULL, *params[0], &retval, arg_count-1, params+1, 1)==SUCCESS) {
  1529. *return_value = retval;
  1530. } else {
  1531. php_error(E_WARNING,"Unable to call %s() - function does not exist", (*params[0])->value.str.val);
  1532. }
  1533. efree(params);
  1534. }
  1535. PHP_FUNCTION(call_user_method)
  1536. {
  1537. pval ***params;
  1538. pval retval;
  1539. int arg_count=ARG_COUNT(ht);
  1540. CLS_FETCH();
  1541. if (arg_count<2) {
  1542. WRONG_PARAM_COUNT;
  1543. }
  1544. params = (pval ***) emalloc(sizeof(pval **)*arg_count);
  1545. if (getParametersArrayEx(arg_count, params)==FAILURE) {
  1546. efree(params);
  1547. RETURN_FALSE;
  1548. }
  1549. if ((*params[1])->type != IS_OBJECT) {
  1550. php_error(E_WARNING,"2nd argument is not an object\n");
  1551. efree(params);
  1552. RETURN_FALSE;
  1553. }
  1554. SEPARATE_ZVAL(params[0]);
  1555. SEPARATE_ZVAL(params[1]);
  1556. convert_to_string(*params[0]);
  1557. if (call_user_function_ex(CG(function_table), *params[1], *params[0], &retval, arg_count-2, params+2, 1)==SUCCESS) {
  1558. *return_value = retval;
  1559. } else {
  1560. php_error(E_WARNING,"Unable to call %s() - function does not exist", (*params[0])->value.str.val);
  1561. }
  1562. efree(params);
  1563. }
  1564. int user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry)
  1565. {
  1566. pval retval;
  1567. int i;
  1568. CLS_FETCH();
  1569. if (call_user_function(CG(function_table), NULL, shutdown_function_entry->arguments[0], &retval, shutdown_function_entry->arg_count-1, shutdown_function_entry->arguments+1)==SUCCESS) {
  1570. pval_destructor(&retval);
  1571. }
  1572. for (i=0; i<shutdown_function_entry->arg_count; i++) {
  1573. zval_ptr_dtor(&shutdown_function_entry->arguments[i]);
  1574. }
  1575. efree(shutdown_function_entry->arguments);
  1576. return 1;
  1577. }
  1578. void php3_call_shutdown_functions(void)
  1579. {
  1580. if (user_shutdown_function_names) {
  1581. zend_hash_destroy(user_shutdown_function_names);
  1582. efree(user_shutdown_function_names);
  1583. }
  1584. }
  1585. /* {{{ proto void register_shutdown_function(string function_name)
  1586. Register a user-level function to be called on request termination */
  1587. PHP_FUNCTION(register_shutdown_function)
  1588. {
  1589. php_shutdown_function_entry shutdown_function_entry;
  1590. int i;
  1591. shutdown_function_entry.arg_count = ARG_COUNT(ht);
  1592. if (shutdown_function_entry.arg_count<1) {
  1593. WRONG_PARAM_COUNT;
  1594. }
  1595. shutdown_function_entry.arguments = (pval **) emalloc(sizeof(pval *)*shutdown_function_entry.arg_count);
  1596. if (getParametersArray(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments)==FAILURE) {
  1597. RETURN_FALSE;
  1598. }
  1599. convert_to_string(shutdown_function_entry.arguments[0]);
  1600. if (!user_shutdown_function_names) {
  1601. user_shutdown_function_names = (HashTable *) emalloc(sizeof(HashTable));
  1602. zend_hash_init(user_shutdown_function_names, 0, NULL, (int (*)(void *))user_shutdown_function_dtor, 0);
  1603. }
  1604. for (i=0; i<shutdown_function_entry.arg_count; i++) {
  1605. shutdown_function_entry.arguments[i]->refcount++;
  1606. }
  1607. zend_hash_next_index_insert(user_shutdown_function_names, &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
  1608. }
  1609. /* }}} */
  1610. ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini)
  1611. {
  1612. syntax_highlighter_ini->highlight_comment = INI_STR("highlight.comment");
  1613. syntax_highlighter_ini->highlight_default = INI_STR("highlight.default");
  1614. syntax_highlighter_ini->highlight_html = INI_STR("highlight.html");
  1615. syntax_highlighter_ini->highlight_keyword = INI_STR("highlight.keyword");
  1616. syntax_highlighter_ini->highlight_string = INI_STR("highlight.string");
  1617. }
  1618. /* {{{ proto void highlight_file(string file_name)
  1619. Syntax highlight a source file */
  1620. PHP_FUNCTION(highlight_file)
  1621. {
  1622. pval *filename;
  1623. zend_syntax_highlighter_ini syntax_highlighter_ini;
  1624. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &filename)==FAILURE) {
  1625. WRONG_PARAM_COUNT;
  1626. }
  1627. convert_to_string(filename);
  1628. php_get_highlight_struct(&syntax_highlighter_ini);
  1629. if (highlight_file(filename->value.str.val, &syntax_highlighter_ini)==FAILURE) {
  1630. RETURN_FALSE;
  1631. }
  1632. RETURN_TRUE;
  1633. }
  1634. /* }}} */
  1635. /* {{{ proto void highlight_string(string string)
  1636. Syntax highlight a string */
  1637. PHP_FUNCTION(highlight_string)
  1638. {
  1639. pval *expr;
  1640. zend_syntax_highlighter_ini syntax_highlighter_ini;
  1641. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &expr)==FAILURE) {
  1642. WRONG_PARAM_COUNT;
  1643. }
  1644. convert_to_string(expr);
  1645. php_get_highlight_struct(&syntax_highlighter_ini);
  1646. if (highlight_string(expr, &syntax_highlighter_ini)==FAILURE) {
  1647. RETURN_FALSE;
  1648. }
  1649. RETURN_TRUE;
  1650. }
  1651. /* }}} */
  1652. pval test_class_get_property(zend_property_reference *property_reference)
  1653. {
  1654. pval result;
  1655. zend_overloaded_element *overloaded_property;
  1656. zend_llist_element *element;
  1657. printf("Reading a property from a TestClass object:\n");
  1658. for (element=property_reference->elements_list.head; element; element=element->next) {
  1659. overloaded_property = (zend_overloaded_element *) element->data;
  1660. switch (overloaded_property->type) {
  1661. case IS_ARRAY:
  1662. printf("Array offset: ");
  1663. break;
  1664. case IS_OBJECT:
  1665. printf("Object property: ");
  1666. break;
  1667. }
  1668. switch (overloaded_property->element.type) {
  1669. case IS_LONG:
  1670. printf("%ld (numeric)\n", overloaded_property->element.value.lval);
  1671. break;
  1672. case IS_STRING:
  1673. printf("'%s'\n", overloaded_property->element.value.str.val);
  1674. break;
  1675. }
  1676. pval_destructor(&overloaded_property->element);
  1677. }
  1678. result.value.str.val = estrndup("testing", 7);
  1679. result.value.str.len = 7;
  1680. result.type = IS_STRING;
  1681. return result;
  1682. }
  1683. int test_class_set_property(zend_property_reference *property_reference, pval *value)
  1684. {
  1685. zend_overloaded_element *overloaded_property;
  1686. zend_llist_element *element;
  1687. printf("Writing to a property from a TestClass object:\n");
  1688. printf("Writing '");
  1689. zend_print_variable(value);
  1690. printf("'\n");
  1691. for (element=property_reference->elements_list.head; element; element=element->next) {
  1692. overloaded_property = (zend_overloaded_element *) element->data;
  1693. switch (overloaded_property->type) {
  1694. case IS_ARRAY:
  1695. printf("Array offset: ");
  1696. break;
  1697. case IS_OBJECT:
  1698. printf("Object property: ");
  1699. break;
  1700. }
  1701. switch (overloaded_property->element.type) {
  1702. case IS_LONG:
  1703. printf("%ld (numeric)\n", overloaded_property->element.value.lval);
  1704. break;
  1705. case IS_STRING:
  1706. printf("'%s'\n", overloaded_property->element.value.str.val);
  1707. break;
  1708. }
  1709. pval_destructor(&overloaded_property->element);
  1710. }
  1711. return 0;
  1712. }
  1713. void test_class_call_function(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
  1714. {
  1715. zend_overloaded_element *overloaded_property;
  1716. zend_llist_element *element;
  1717. printf("Reading a property from a TestClass object:\n");
  1718. for (element=property_reference->elements_list.head; element; element=element->next) {
  1719. overloaded_property = (zend_overloaded_element *) element->data;
  1720. switch (overloaded_property->type) {
  1721. case IS_ARRAY:
  1722. printf("Array offset: ");
  1723. break;
  1724. case IS_OBJECT:
  1725. printf("Object property: ");
  1726. break;
  1727. case IS_METHOD:
  1728. printf("Overloaded method: ");
  1729. }
  1730. switch (overloaded_property->element.type) {
  1731. case IS_LONG:
  1732. printf("%ld (numeric)\n", overloaded_property->element.value.lval);
  1733. break;
  1734. case IS_STRING:
  1735. printf("'%s'\n", overloaded_property->element.value.str.val);
  1736. break;
  1737. }
  1738. pval_destructor(&overloaded_property->element);
  1739. }
  1740. printf("%d arguments\n", ARG_COUNT(ht));
  1741. return_value->value.str.val = estrndup("testing", 7);
  1742. return_value->value.str.len = 7;
  1743. return_value->type = IS_STRING;
  1744. }
  1745. void test_class_startup()
  1746. {
  1747. zend_class_entry test_class_entry;
  1748. INIT_OVERLOADED_CLASS_ENTRY(test_class_entry, "OverloadedTestClass", NULL,
  1749. test_class_call_function,
  1750. test_class_get_property,
  1751. test_class_set_property);
  1752. register_internal_class(&test_class_entry);
  1753. }
  1754. PHP_FUNCTION(ob_start)
  1755. {
  1756. php_start_ob_buffering();
  1757. }
  1758. PHP_FUNCTION(ob_end_flush)
  1759. {
  1760. php_end_ob_buffering(1);
  1761. }
  1762. PHP_FUNCTION(ob_end_clean)
  1763. {
  1764. php_end_ob_buffering(0);
  1765. }
  1766. PHP_FUNCTION(ob_get_contents)
  1767. {
  1768. if (php_ob_get_buffer(return_value)==FAILURE) {
  1769. RETURN_FALSE;
  1770. }
  1771. }
  1772. PHP_FUNCTION(ini_get)
  1773. {
  1774. pval *varname;
  1775. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &varname)==FAILURE) {
  1776. WRONG_PARAM_COUNT;
  1777. }
  1778. return_value->value.str.val = php_ini_string(varname->value.str.val, varname->value.str.len+1, 0);
  1779. if (!return_value->value.str.val) {
  1780. RETURN_FALSE;
  1781. }
  1782. return_value->value.str.len = strlen(return_value->value.str.val);
  1783. return_value->type = IS_STRING;
  1784. pval_copy_constructor(return_value);
  1785. }
  1786. PHP_FUNCTION(ini_alter)
  1787. {
  1788. pval *varname, *new_value;
  1789. char *old_value;
  1790. if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &varname, &new_value)==FAILURE) {
  1791. WRONG_PARAM_COUNT;
  1792. }
  1793. old_value = php_ini_string(varname->value.str.val, varname->value.str.len+1, 0);
  1794. convert_to_string(new_value);
  1795. if (php_alter_ini_entry(varname->value.str.val, varname->value.str.len+1, new_value->value.str.val, new_value->value.str.len, PHP_INI_USER)==FAILURE) {
  1796. RETURN_FALSE;
  1797. }
  1798. if (old_value) {
  1799. RETURN_STRING(old_value, 1);
  1800. } else {
  1801. RETURN_FALSE;
  1802. }
  1803. }
  1804. PHP_FUNCTION(ini_restore)
  1805. {
  1806. pval *varname;
  1807. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &varname)==FAILURE) {
  1808. WRONG_PARAM_COUNT;
  1809. }
  1810. convert_to_string(varname);
  1811. php_restore_ini_entry(varname->value.str.val, varname->value.str.len);
  1812. }
  1813. PHP_FUNCTION(print_r)
  1814. {
  1815. pval *expr;
  1816. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &expr)==FAILURE) {
  1817. WRONG_PARAM_COUNT;
  1818. }
  1819. zend_print_pval_r(expr, 0);
  1820. RETURN_TRUE;
  1821. }
  1822. /* This should go back to PHP */
  1823. /* {{{ proto int connection_aborted(void)
  1824. Returns true if client disconnected */
  1825. PHP_FUNCTION(connection_aborted)
  1826. {
  1827. PLS_FETCH();
  1828. RETURN_LONG(PG(connection_status)&PHP_CONNECTION_ABORTED);
  1829. }
  1830. /* }}} */
  1831. /* {{{ proto int connection_timeout(void)
  1832. Returns true if script timed out */
  1833. PHP_FUNCTION(connection_timeout)
  1834. {
  1835. PLS_FETCH();
  1836. RETURN_LONG(PG(connection_status)&PHP_CONNECTION_TIMEOUT);
  1837. }
  1838. /* }}} */
  1839. /* {{{ proto int connection_status(void)
  1840. Returns the connection status bitfield */
  1841. PHP_FUNCTION(connection_status)
  1842. {
  1843. PLS_FETCH();
  1844. RETURN_LONG(PG(connection_status));
  1845. }
  1846. /* }}} */
  1847. /* {{{ proto int ignore_user_abort(boolean value)
  1848. Set whether we want to ignore a user abort event or not */
  1849. PHP_FUNCTION(ignore_user_abort)
  1850. {
  1851. pval *arg;
  1852. int old_setting;
  1853. PLS_FETCH();
  1854. old_setting = PG(ignore_user_abort);
  1855. switch (ARG_COUNT(ht)) {
  1856. case 0:
  1857. break;
  1858. case 1:
  1859. if (getParameters(ht,1,&arg) == FAILURE) {
  1860. RETURN_FALSE;
  1861. }
  1862. convert_to_boolean(arg);
  1863. PG(ignore_user_abort) = (zend_bool) arg->value.lval;
  1864. break;
  1865. default:
  1866. WRONG_PARAM_COUNT;
  1867. break;
  1868. }
  1869. RETURN_LONG(old_setting);
  1870. }
  1871. /* }}} */
  1872. /* {{{ proto bool function_exists(string function_name)
  1873. Checks if a given function has been defined */
  1874. PHP_FUNCTION(function_exists)
  1875. {
  1876. pval *fname;
  1877. pval *tmp;
  1878. char *lcname;
  1879. CLS_FETCH();
  1880. if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &fname)==FAILURE) {
  1881. WRONG_PARAM_COUNT;
  1882. }
  1883. lcname = estrdup(fname->value.str.val);
  1884. zend_str_tolower(lcname, fname->value.str.len);
  1885. if (zend_hash_find(CG(function_table), lcname,
  1886. fname->value.str.len+1, (void**)&tmp) == FAILURE) {
  1887. efree(lcname);
  1888. RETURN_FALSE;
  1889. } else {
  1890. efree(lcname);
  1891. RETURN_TRUE;
  1892. }
  1893. }
  1894. /* }}} */
  1895. /* {{{ proto bool in_array(mixed needle, array haystack)
  1896. Checks if the given value exists in the array */
  1897. PHP_FUNCTION(in_array)
  1898. {
  1899. zval *value, /* value to check for */
  1900. *array, /* array to check in */
  1901. **entry_ptr, /* pointer to array entry */
  1902. *entry, /* actual array entry */
  1903. res; /* comparison result */
  1904. HashTable *target_hash; /* array hashtable */
  1905. if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &value, &array) == FAILURE) {
  1906. WRONG_PARAM_COUNT;
  1907. }
  1908. if (value->type == IS_ARRAY || value->type == IS_OBJECT) {
  1909. zend_error(E_WARNING, "Wrong datatype for first argument in call to in_array()");
  1910. return;
  1911. }
  1912. if (array->type != IS_ARRAY) {
  1913. zend_error(E_WARNING, "Wrong datatype for second argument in call to in_array()");
  1914. return;
  1915. }
  1916. target_hash = HASH_OF(array);
  1917. zend_hash_internal_pointer_reset(target_hash);
  1918. while(zend_hash_get_current_data(target_hash, (void **)&entry_ptr) == SUCCESS) {
  1919. entry = *entry_ptr;
  1920. is_equal_function(&res, value, entry);
  1921. if (zval_is_true(&res)) {
  1922. RETURN_TRUE;
  1923. }
  1924. zend_hash_move_forward(target_hash);
  1925. }
  1926. RETURN_FALSE;
  1927. }
  1928. /* }}} */
  1929. /* {{{ int _valid_var_name(char *varname) */
  1930. static int _valid_var_name(char *varname)
  1931. {
  1932. int len, i;
  1933. if (!varname)
  1934. return 0;
  1935. len = strlen(varname);
  1936. if (!isalpha((int)varname[0]) && varname[0] != '_')
  1937. return 0;
  1938. if (len > 1) {
  1939. for(i=1; i<len; i++) {
  1940. if (!isalnum((int)varname[i]) && varname[i] != '_') {
  1941. return 0;
  1942. }
  1943. }
  1944. }
  1945. return 1;
  1946. }
  1947. /* }}} */
  1948. /* {{{ proto void extract(array var_array, int extract_type [, string prefix])
  1949. Imports variables into symbol table from an array */
  1950. PHP_FUNCTION(extract)
  1951. {
  1952. zval *var_array, *etype, *prefix;
  1953. zval **entry_ptr, *entry, *exist;
  1954. zval *data;
  1955. char *varname, *finalname;
  1956. ulong lkey;
  1957. int res, extype;
  1958. ELS_FETCH();
  1959. switch(ARG_COUNT(ht)) {
  1960. case 1:
  1961. if (getParameters(ht, 1, &var_array) == FAILURE) {
  1962. WRONG_PARAM_COUNT;
  1963. }
  1964. extype = EXTR_OVERWRITE;
  1965. break;
  1966. case 2:
  1967. if (getParameters(ht, 2, &var_array, &etype) == FAILURE) {
  1968. WRONG_PARAM_COUNT;
  1969. }
  1970. convert_to_long(etype);
  1971. extype = etype->value.lval;
  1972. if (extype > EXTR_SKIP && extype <= EXTR_PREFIX_ALL) {
  1973. WRONG_PARAM_COUNT;
  1974. }
  1975. break;
  1976. case 3:
  1977. if (getParameters(ht, 3, &var_array, &etype, &prefix) == FAILURE) {
  1978. WRONG_PARAM_COUNT;
  1979. }
  1980. convert_to_long(etype);
  1981. extype = etype->value.lval;
  1982. break;
  1983. default:
  1984. WRONG_PARAM_COUNT;
  1985. break;
  1986. }
  1987. if (extype < EXTR_OVERWRITE || extype > EXTR_PREFIX_ALL) {
  1988. zend_error(E_WARNING, "Wrong argument in call to extract()");
  1989. return;
  1990. }
  1991. if (var_array->type != IS_ARRAY) {
  1992. zend_error(E_WARNING, "Wrong datatype in call to extract()");
  1993. return;
  1994. }
  1995. zend_hash_internal_pointer_reset(var_array->value.ht);
  1996. while(zend_hash_get_current_data(var_array->value.ht, (void **)&entry_ptr) == SUCCESS) {
  1997. entry = *entry_ptr;
  1998. if (zend_hash_get_current_key(var_array->value.ht, &varname, &lkey) ==
  1999. HASH_KEY_IS_STRING) {
  2000. if (_valid_var_name(varname)) {
  2001. finalname = NULL;
  2002. res = zend_hash_find(EG(active_symbol_table),
  2003. varname, strlen(varname)+1, (void**)&exist);
  2004. switch (extype) {
  2005. case EXTR_OVERWRITE:
  2006. finalname = estrdup(varname);
  2007. break;
  2008. case EXTR_PREFIX_SAME:
  2009. if (res != SUCCESS)
  2010. finalname = estrdup(varname);
  2011. /* break omitted intentionally */
  2012. case EXTR_PREFIX_ALL:
  2013. if (!finalname) {
  2014. finalname = emalloc(strlen(varname) + prefix->value.str.len + 2);
  2015. strcpy(finalname, prefix->value.str.val);
  2016. strcat(finalname, "_");
  2017. strcat(finalname, varname);
  2018. }
  2019. break;
  2020. default:
  2021. if (res != SUCCESS)
  2022. finalname = estrdup(varname);
  2023. break;
  2024. }
  2025. if (finalname) {
  2026. data = (zval *)emalloc(sizeof(zval));
  2027. *data = *entry;
  2028. zval_copy_ctor(data);
  2029. INIT_PZVAL(data);
  2030. zend_hash_update(EG(active_symbol_table), finalname,
  2031. strlen(finalname)+1, &data, sizeof(zval *), NULL);
  2032. efree(finalname);
  2033. }
  2034. }
  2035. efree(varname);
  2036. }
  2037. zend_hash_move_forward(var_array->value.ht);
  2038. }
  2039. }
  2040. /* }}} */
  2041. /* {{{ void _compact_var(HashTable *eg_active_symbol_table, zval *return_value, zval *entry) */
  2042. static void _compact_var(HashTable *eg_active_symbol_table, zval *return_value, zval *entry)
  2043. {
  2044. zval **value_ptr, *value, *data;
  2045. if (entry->type == IS_STRING) {
  2046. if (zend_hash_find(eg_active_symbol_table, entry->value.str.val,
  2047. entry->value.str.len+1, (void **)&value_ptr) != FAILURE) {
  2048. value = *value_ptr;
  2049. data = (zval *)emalloc(sizeof(zval));
  2050. *data = *value;
  2051. zval_copy_ctor(data);
  2052. INIT_PZVAL(data);
  2053. zend_hash_update(return_value->value.ht, entry->value.str.val,
  2054. entry->value.str.len+1, &data, sizeof(zval *), NULL);
  2055. }
  2056. }
  2057. else if (entry->type == IS_ARRAY) {
  2058. zend_hash_internal_pointer_reset(entry->value.ht);
  2059. while(zend_hash_get_current_data(entry->value.ht, (void**)&value_ptr) == SUCCESS) {
  2060. value = *value_ptr;
  2061. _compact_var(eg_active_symbol_table, return_value, value);
  2062. zend_hash_move_forward(entry->value.ht);
  2063. }
  2064. }
  2065. }
  2066. /* }}} */
  2067. /* {{{ proto array compact(string var_name | array var_names [, ... ])
  2068. Creates a hash containing variables and their values */
  2069. PHP_FUNCTION(compact)
  2070. {
  2071. zval **args; /* function arguments array */
  2072. int i;
  2073. ELS_FETCH();
  2074. args = (zval **)emalloc(ARG_COUNT(ht) * sizeof(zval *));
  2075. if (getParametersArray(ht, ARG_COUNT(ht), args) == FAILURE) {
  2076. efree(args);
  2077. WRONG_PARAM_COUNT;
  2078. }
  2079. array_init(return_value);
  2080. for (i=0; i<ARG_COUNT(ht); i++)
  2081. {
  2082. _compact_var(EG(active_symbol_table), return_value, args[i]);
  2083. }
  2084. efree(args);
  2085. }
  2086. /* }}} */
  2087. /* {{{ proto array range(int low, int high)
  2088. Create an array containing the range of integers from low to high (inclusive) */
  2089. PHP_FUNCTION(range)
  2090. {
  2091. zval *zlow, *zhigh;
  2092. int low, high;
  2093. if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&zlow,&zhigh) == FAILURE) {
  2094. WRONG_PARAM_COUNT;
  2095. }
  2096. convert_to_long(zlow);
  2097. convert_to_long(zhigh);
  2098. low = zlow->value.lval;
  2099. high = zhigh->value.lval;
  2100. /* allocate an array for return */
  2101. if (array_init(return_value) == FAILURE) {
  2102. RETURN_FALSE;
  2103. }
  2104. for (; low <= high; low++) {
  2105. add_next_index_long(return_value, low);
  2106. }
  2107. }
  2108. /* }}} */
  2109. static int array_data_shuffle(const void *a, const void*b) {
  2110. return (
  2111. /* This is just a little messy. */
  2112. #ifdef HAVE_LRAND48
  2113. lrand48()
  2114. #else
  2115. #ifdef HAVE_RANDOM
  2116. random()
  2117. #else
  2118. rand()
  2119. #endif
  2120. #endif
  2121. % 2) ? 1 : -1;
  2122. }
  2123. /* {{{ proto int shuffle(array array_arg)
  2124. Randomly shuffle the contents of an array */
  2125. PHP_FUNCTION(shuffle)
  2126. {
  2127. zval **array;
  2128. if (ARG_COUNT(ht) != 1 || getParametersEx(1, &array) == FAILURE) {
  2129. WRONG_PARAM_COUNT;
  2130. }
  2131. if ((*array)->type != IS_ARRAY) {
  2132. php_error(E_WARNING, "Wrong datatype in shuffle() call");
  2133. return;
  2134. }
  2135. if (!ParameterPassedByReference(ht,1)) {
  2136. php_error(E_WARNING, "Array not passed by reference in call to shuffle()");
  2137. return;
  2138. }
  2139. if (zend_hash_sort((*array)->value.ht, array_data_shuffle, 1) == FAILURE) {
  2140. return;
  2141. }
  2142. RETURN_TRUE;
  2143. }
  2144. /* }}} */
  2145. /* HashTable* _phpi_splice(HashTable *in_hash, int offset, int length,
  2146. zval ***list, int list_count, HashTable **removed) */
  2147. HashTable* _phpi_splice(HashTable *in_hash, int offset, int length,
  2148. zval ***list, int list_count, HashTable **removed)
  2149. {
  2150. HashTable *out_hash = NULL; /* Output hashtable */
  2151. int num_in, /* Number of entries in the input hashtable */
  2152. pos, /* Current position in the hashtable */
  2153. i; /* Loop counter */
  2154. Bucket *p; /* Pointer to hash bucket */
  2155. zval *entry; /* Hash entry */
  2156. /* If input hash doesn't exist, we have nothing to do */
  2157. if (!in_hash)
  2158. return NULL;
  2159. /* Get number of entries in the input hash */
  2160. num_in = zend_hash_num_elements(in_hash);
  2161. /* Clamp the offset.. */
  2162. if (offset > num_in)
  2163. offset = num_in;
  2164. else if (offset < 0 && (offset=num_in+offset) < 0)
  2165. offset = 0;
  2166. /* ..and the length */
  2167. if (length < 0)
  2168. length = num_in-offset+length;
  2169. else if(offset+length > num_in)
  2170. length = num_in-offset;
  2171. /* Create and initialize output hash */
  2172. out_hash = (HashTable *)emalloc(sizeof(HashTable));
  2173. zend_hash_init(out_hash, 0, NULL, PVAL_PTR_DTOR, 0);
  2174. /* Start at the beginning of the input hash and copy
  2175. entries to output hash until offset is reached */
  2176. for (pos=0, p=in_hash->pListHead; pos<offset && p ; pos++, p=p->pListNext) {
  2177. /* Get entry and increase reference count */
  2178. entry = *((zval **)p->pData);
  2179. entry->refcount++;
  2180. /* Update output hash depending on key type */
  2181. if (p->nKeyLength)
  2182. zend_hash_update(out_hash, p->arKey, p->nKeyLength, &entry, sizeof(zval *), NULL);
  2183. else
  2184. zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);
  2185. }
  2186. /* If hash for removed entries exists, go until offset+length
  2187. and copy the entries to it */
  2188. if (removed != NULL) {
  2189. for( ; pos<offset+length && p; pos++, p=p->pListNext) {
  2190. entry = *((zval **)p->pData);
  2191. entry->refcount++;
  2192. if (p->nKeyLength)
  2193. zend_hash_update(*removed, p->arKey, p->nKeyLength, &entry, sizeof(zval *), NULL);
  2194. else
  2195. zend_hash_next_index_insert(*removed, &entry, sizeof(zval *), NULL);
  2196. }
  2197. } else /* otherwise just skip those entries */
  2198. for( ; pos<offset+length && p; pos++, p=p->pListNext);
  2199. /* If there are entries to insert.. */
  2200. if (list != NULL) {
  2201. /* ..for each one, create a new zval, copy entry into it
  2202. and copy it into the output hash */
  2203. for (i=0; i<list_count; i++) {
  2204. entry = *list[i];
  2205. entry->refcount++;
  2206. zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);
  2207. }
  2208. }
  2209. /* Copy the remaining input hash entries to the output hash */
  2210. for ( ; p ; p=p->pListNext) {
  2211. entry = *((zval **)p->pData);
  2212. entry->refcount++;
  2213. if (p->nKeyLength)
  2214. zend_hash_update(out_hash, p->arKey, p->nKeyLength, &entry, sizeof(zval *), NULL);
  2215. else
  2216. zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);
  2217. }
  2218. zend_hash_internal_pointer_reset(out_hash);
  2219. return out_hash;
  2220. }
  2221. /* }}} */
  2222. /* {{{ proto int array_push(array stack, mixed var [, ...])
  2223. Pushes elements onto the end of the array */
  2224. PHP_FUNCTION(array_push)
  2225. {
  2226. zval ***args, /* Function arguments array */
  2227. *stack, /* Input array */
  2228. *new_var; /* Variable to be pushed */
  2229. int i, /* Loop counter */
  2230. argc; /* Number of function arguments */
  2231. /* Get the argument count and check it */
  2232. argc = ARG_COUNT(ht);
  2233. if (argc < 2) {
  2234. WRONG_PARAM_COUNT;
  2235. }
  2236. /* Allocate arguments array and get the arguments, checking for errors. */
  2237. args = (zval ***)emalloc(argc * sizeof(zval **));
  2238. if (getParametersArrayEx(argc, args) == FAILURE) {
  2239. efree(args);
  2240. WRONG_PARAM_COUNT;
  2241. }
  2242. /* Get first argument and check that it's an array */
  2243. stack = *args[0];
  2244. if (stack->type != IS_ARRAY) {
  2245. zend_error(E_WARNING, "First argument to array_push() needs to be an array");
  2246. RETURN_FALSE;
  2247. }
  2248. /* For each subsequent argument, make it a reference, increase refcount,
  2249. and add it to the end of the array */
  2250. for (i=1; i<argc; i++) {
  2251. new_var = *args[i];
  2252. new_var->refcount++;
  2253. zend_hash_next_index_insert(stack->value.ht, &new_var, sizeof(zval *), NULL);
  2254. }
  2255. /* Clean up and return the number of values in the stack */
  2256. efree(args);
  2257. RETVAL_LONG(zend_hash_num_elements(stack->value.ht));
  2258. }
  2259. /* }}} */
  2260. /* {{{ void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int which_end) */
  2261. static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
  2262. {
  2263. zval **stack, /* Input stack */
  2264. **val; /* Value to be popped */
  2265. HashTable *new_hash; /* New stack */
  2266. /* Get the arguments and do error-checking */
  2267. if (ARG_COUNT(ht) != 1 || getParametersEx(1, &stack) == FAILURE) {
  2268. WRONG_PARAM_COUNT;
  2269. }
  2270. if ((*stack)->type != IS_ARRAY) {
  2271. zend_error(E_WARNING, "The argument needs to be an array");
  2272. return;
  2273. }
  2274. if (zend_hash_num_elements((*stack)->value.ht) == 0) {
  2275. return;
  2276. }
  2277. /* Get the first or last value and copy it into the return value */
  2278. if (off_the_end)
  2279. zend_hash_internal_pointer_end((*stack)->value.ht);
  2280. else
  2281. zend_hash_internal_pointer_reset((*stack)->value.ht);
  2282. zend_hash_get_current_data((*stack)->value.ht, (void **)&val);
  2283. *return_value = **val;
  2284. zval_copy_ctor(return_value);
  2285. INIT_PZVAL(return_value);
  2286. /* Delete the first or last value */
  2287. new_hash = _phpi_splice((*stack)->value.ht, (off_the_end) ? -1 : 0, 1, NULL, 0, NULL);
  2288. zend_hash_destroy((*stack)->value.ht);
  2289. efree((*stack)->value.ht);
  2290. (*stack)->value.ht = new_hash;
  2291. }
  2292. /* }}} */
  2293. /* {{{ proto mixed array_pop(array stack)
  2294. Pops an element off the end of the array */
  2295. PHP_FUNCTION(array_pop)
  2296. {
  2297. _phpi_pop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  2298. }
  2299. /* }}} */
  2300. /* {{{ proto mixed array_shift(array stack)
  2301. Pops an element off the beginning of the array */
  2302. PHP_FUNCTION(array_shift)
  2303. {
  2304. _phpi_pop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  2305. }
  2306. /* }}} */
  2307. /* {{{ proto int array_unshift(array stack, mixed var [, ...])
  2308. Pushes elements onto the beginning of the array */
  2309. PHP_FUNCTION(array_unshift)
  2310. {
  2311. zval ***args, /* Function arguments array */
  2312. *stack; /* Input stack */
  2313. HashTable *new_hash; /* New hashtable for the stack */
  2314. int argc; /* Number of function arguments */
  2315. /* Get the argument count and check it */
  2316. argc = ARG_COUNT(ht);
  2317. if (argc < 2) {
  2318. WRONG_PARAM_COUNT;
  2319. }
  2320. /* Allocate arguments array and get the arguments, checking for errors. */
  2321. args = (zval ***)emalloc(argc * sizeof(zval **));
  2322. if (getParametersArrayEx(argc, args) == FAILURE) {
  2323. efree(args);
  2324. WRONG_PARAM_COUNT;
  2325. }
  2326. /* Get first argument and check that it's an array */
  2327. stack = *args[0];
  2328. if (stack->type != IS_ARRAY) {
  2329. zend_error(E_WARNING, "First argument to array_unshift() needs to be an array");
  2330. RETURN_FALSE;
  2331. }
  2332. /* Use splice to insert the elements at the beginning. Destroy old
  2333. hashtable and replace it with new one */
  2334. new_hash = _phpi_splice(stack->value.ht, 0, 0, &args[1], argc-1, NULL);
  2335. zend_hash_destroy(stack->value.ht);
  2336. efree(stack->value.ht);
  2337. stack->value.ht = new_hash;
  2338. /* Clean up and return the number of elements in the stack */
  2339. efree(args);
  2340. RETVAL_LONG(zend_hash_num_elements(stack->value.ht));
  2341. }
  2342. /* }}} */
  2343. /* {{{ proto array array_splice(array input, int offset [, int length [, array replacement]])
  2344. Removes the elements designated by offset and length and replace them with
  2345. supplied array */
  2346. PHP_FUNCTION(array_splice)
  2347. {
  2348. zval ***args, /* Function arguments array */
  2349. *array, /* Input array */
  2350. ***repl = NULL; /* Replacement elements */
  2351. HashTable *new_hash = NULL; /* Output array's hash */
  2352. Bucket *p; /* Bucket used for traversing hash */
  2353. int argc, /* Number of function arguments */
  2354. i,
  2355. offset,
  2356. length,
  2357. repl_num = 0; /* Number of replacement elements */
  2358. /* Get the argument count and check it */
  2359. argc = ARG_COUNT(ht);
  2360. if (argc < 2 || argc > 4) {
  2361. WRONG_PARAM_COUNT;
  2362. }
  2363. /* Allocate arguments array and get the arguments, checking for errors. */
  2364. args = (zval ***)emalloc(argc * sizeof(zval **));
  2365. if (getParametersArrayEx(argc, args) == FAILURE) {
  2366. efree(args);
  2367. WRONG_PARAM_COUNT;
  2368. }
  2369. /* Get first argument and check that it's an array */
  2370. array = *args[0];
  2371. if (array->type != IS_ARRAY) {
  2372. zend_error(E_WARNING, "First argument to array_splice() should be an array");
  2373. efree(args);
  2374. return;
  2375. }
  2376. /* Get the next two arguments. If length is omitted,
  2377. it's assumed to be until the end of the array */
  2378. convert_to_long_ex(args[1]);
  2379. offset = (*args[1])->value.lval;
  2380. if (argc > 2) {
  2381. convert_to_long_ex(args[2]);
  2382. length = (*args[2])->value.lval;
  2383. } else
  2384. length = zend_hash_num_elements(array->value.ht);
  2385. if (argc == 4) {
  2386. /* Make sure the last argument, if passed, is an array */
  2387. convert_to_array_ex(args[3]);
  2388. /* Create the array of replacement elements */
  2389. repl_num = zend_hash_num_elements((*args[3])->value.ht);
  2390. repl = (zval ***)emalloc(repl_num * sizeof(zval **));
  2391. for (p=(*args[3])->value.ht->pListHead, i=0; p; p=p->pListNext, i++) {
  2392. repl[i] = ((zval **)p->pData);
  2393. }
  2394. }
  2395. /* Initialize return value */
  2396. array_init(return_value);
  2397. /* Perform splice */
  2398. new_hash = _phpi_splice(array->value.ht, offset, length,
  2399. repl, repl_num,
  2400. &return_value->value.ht);
  2401. /* Replace input array's hashtable with the new one */
  2402. zend_hash_destroy(array->value.ht);
  2403. efree(array->value.ht);
  2404. array->value.ht = new_hash;
  2405. /* Clean up */
  2406. if (argc == 4)
  2407. efree(repl);
  2408. efree(args);
  2409. }
  2410. /* }}} */
  2411. /* {{{ proto array array_slice(array input, int offset [, int length])
  2412. Returns elements specified by offset and length */
  2413. PHP_FUNCTION(array_slice)
  2414. {
  2415. zval **input, /* Input array */
  2416. **offset, /* Offset to get elements from */
  2417. **length, /* How many elements to get */
  2418. **entry; /* An array entry */
  2419. int offset_val, /* Value of the offset argument */
  2420. length_val, /* Value of the length argument */
  2421. num_in, /* Number of elements in the input array */
  2422. pos, /* Current position in the array */
  2423. argc; /* Number of function arguments */
  2424. char *string_key;
  2425. ulong num_key;
  2426. /* Get the arguments and do error-checking */
  2427. argc = ARG_COUNT(ht);
  2428. if (argc < 2 || argc > 3 || getParametersEx(argc, &input, &offset, &length)) {
  2429. WRONG_PARAM_COUNT;
  2430. }
  2431. if ((*input)->type != IS_ARRAY) {
  2432. zend_error(E_WARNING, "First argument to array_slice() should be an array");
  2433. return;
  2434. }
  2435. /* Make sure offset and length are integers and assume
  2436. we want all entries from offset to the end if length
  2437. is not passed */
  2438. convert_to_long_ex(offset);
  2439. offset_val = (*offset)->value.lval;
  2440. if (argc == 3) {
  2441. convert_to_long_ex(length);
  2442. length_val = (*length)->value.lval;
  2443. } else
  2444. length_val = zend_hash_num_elements((*input)->value.ht);
  2445. /* Initialize returned array */
  2446. array_init(return_value);
  2447. /* Get number of entries in the input hash */
  2448. num_in = zend_hash_num_elements((*input)->value.ht);
  2449. /* Clamp the offset.. */
  2450. if (offset_val > num_in)
  2451. return;
  2452. else if (offset_val < 0 && (offset_val=num_in+offset_val) < 0)
  2453. offset_val = 0;
  2454. /* ..and the length */
  2455. if (length_val < 0)
  2456. length_val = num_in-offset_val+length_val;
  2457. else if(offset_val+length_val > num_in)
  2458. length_val = num_in-offset_val;
  2459. if (length_val == 0)
  2460. return;
  2461. /* Start at the beginning and go until we hit offset */
  2462. pos = 0;
  2463. zend_hash_internal_pointer_reset((*input)->value.ht);
  2464. while(pos < offset_val &&
  2465. zend_hash_get_current_data((*input)->value.ht, (void **)&entry) == SUCCESS) {
  2466. pos++;
  2467. zend_hash_move_forward((*input)->value.ht);
  2468. }
  2469. /* Copy elements from input array to the one that's returned */
  2470. while(pos < offset_val+length_val &&
  2471. zend_hash_get_current_data((*input)->value.ht, (void **)&entry) == SUCCESS) {
  2472. (*entry)->refcount++;
  2473. switch (zend_hash_get_current_key((*input)->value.ht, &string_key, &num_key)) {
  2474. case HASH_KEY_IS_STRING:
  2475. zend_hash_update(return_value->value.ht, string_key, strlen(string_key)+1,
  2476. entry, sizeof(zval *), NULL);
  2477. efree(string_key);
  2478. break;
  2479. case HASH_KEY_IS_LONG:
  2480. zend_hash_next_index_insert(return_value->value.ht,
  2481. entry, sizeof(zval *), NULL);
  2482. break;
  2483. }
  2484. pos++;
  2485. zend_hash_move_forward((*input)->value.ht);
  2486. }
  2487. }
  2488. /* }}} */
  2489. /* {{{ proto array array_merge(array arr1, array arr2 [, ...])
  2490. Merges elements from passed arrays into one array */
  2491. PHP_FUNCTION(array_merge)
  2492. {
  2493. zval ***args = NULL,
  2494. **entry;
  2495. HashTable *hash;
  2496. int argc,
  2497. i;
  2498. char *string_key;
  2499. ulong num_key;
  2500. /* Get the argument count and check it */
  2501. argc = ARG_COUNT(ht);
  2502. if (argc < 2) {
  2503. WRONG_PARAM_COUNT;
  2504. }
  2505. /* Allocate arguments array and get the arguments, checking for errors. */
  2506. args = (zval ***)emalloc(argc * sizeof(zval **));
  2507. if (getParametersArrayEx(argc, args) == FAILURE) {
  2508. efree(args);
  2509. WRONG_PARAM_COUNT;
  2510. }
  2511. array_init(return_value);
  2512. for (i=0; i<argc; i++) {
  2513. if ((*args[i])->type != IS_ARRAY) {
  2514. zend_error(E_WARNING, "Skipping argument #%d to array_merge(), since it's not an array", i+1);
  2515. continue;
  2516. }
  2517. hash = (*args[i])->value.ht;
  2518. zend_hash_internal_pointer_reset(hash);
  2519. while(zend_hash_get_current_data(hash, (void **)&entry) == SUCCESS) {
  2520. (*entry)->refcount++;
  2521. switch (zend_hash_get_current_key(hash, &string_key, &num_key)) {
  2522. case HASH_KEY_IS_STRING:
  2523. zend_hash_update(return_value->value.ht, string_key, strlen(string_key)+1,
  2524. entry, sizeof(zval *), NULL);
  2525. efree(string_key);
  2526. break;
  2527. case HASH_KEY_IS_LONG:
  2528. zend_hash_next_index_insert(return_value->value.ht,
  2529. entry, sizeof(zval *), NULL);
  2530. break;
  2531. }
  2532. zend_hash_move_forward(hash);
  2533. }
  2534. }
  2535. efree(args);
  2536. }
  2537. /* }}} */
  2538. /* {{{ proto array array_keys(array input [, mixed search_value])
  2539. Return just the keys from the input array, optionally only
  2540. for the specified search_value */
  2541. PHP_FUNCTION(array_keys)
  2542. {
  2543. zval **input, /* Input array */
  2544. **search_value, /* Value to search for */
  2545. **entry, /* An entry in the input array */
  2546. res, /* Result of comparison */
  2547. *new_val; /* New value */
  2548. int add_key; /* Flag to indicate whether a key should be added */
  2549. char *string_key; /* String key */
  2550. ulong num_key; /* Numeric key */
  2551. search_value = NULL;
  2552. /* Get arguments and do error-checking */
  2553. if (ARG_COUNT(ht) < 1 || ARG_COUNT(ht) > 2 ||
  2554. getParametersEx(ARG_COUNT(ht), &input, &search_value) == FAILURE) {
  2555. WRONG_PARAM_COUNT;
  2556. }
  2557. if ((*input)->type != IS_ARRAY) {
  2558. zend_error(E_WARNING, "First argument to array_keys() should be an array");
  2559. return;
  2560. }
  2561. /* Initialize return array */
  2562. array_init(return_value);
  2563. add_key = 1;
  2564. /* Go through input array and add keys to the return array */
  2565. zend_hash_internal_pointer_reset((*input)->value.ht);
  2566. while(zend_hash_get_current_data((*input)->value.ht, (void **)&entry) == SUCCESS) {
  2567. if (search_value != NULL) {
  2568. is_equal_function(&res, *search_value, *entry);
  2569. add_key = zval_is_true(&res);
  2570. }
  2571. if (add_key) {
  2572. MAKE_STD_ZVAL(new_val);
  2573. switch (zend_hash_get_current_key((*input)->value.ht, &string_key, &num_key)) {
  2574. case HASH_KEY_IS_STRING:
  2575. new_val->type = IS_STRING;
  2576. new_val->value.str.val = string_key;
  2577. new_val->value.str.len = strlen(string_key);
  2578. zend_hash_next_index_insert(return_value->value.ht, &new_val,
  2579. sizeof(zval *), NULL);
  2580. break;
  2581. case HASH_KEY_IS_LONG:
  2582. new_val->type = IS_LONG;
  2583. new_val->value.lval = num_key;
  2584. zend_hash_next_index_insert(return_value->value.ht, &new_val,
  2585. sizeof(zval *), NULL);
  2586. break;
  2587. }
  2588. }
  2589. zend_hash_move_forward((*input)->value.ht);
  2590. }
  2591. }
  2592. /* }}} */
  2593. /* {{{ proto array array_values(array input)
  2594. Return just the values from the input array */
  2595. PHP_FUNCTION(array_values)
  2596. {
  2597. zval **input, /* Input array */
  2598. **entry; /* An entry in the input array */
  2599. /* Get arguments and do error-checking */
  2600. if (ARG_COUNT(ht) != 1 || getParametersEx(ARG_COUNT(ht), &input) == FAILURE) {
  2601. WRONG_PARAM_COUNT;
  2602. }
  2603. if ((*input)->type != IS_ARRAY) {
  2604. zend_error(E_WARNING, "Argument to array_values() should be an array");
  2605. return;
  2606. }
  2607. /* Initialize return array */
  2608. array_init(return_value);
  2609. /* Go through input array and add values to the return array */
  2610. zend_hash_internal_pointer_reset((*input)->value.ht);
  2611. while(zend_hash_get_current_data((*input)->value.ht, (void **)&entry) == SUCCESS) {
  2612. (*entry)->refcount++;
  2613. zend_hash_next_index_insert(return_value->value.ht, entry,
  2614. sizeof(zval *), NULL);
  2615. zend_hash_move_forward((*input)->value.ht);
  2616. }
  2617. }
  2618. /* }}} */
  2619. /* {{{ proto array array_count_values(array input)
  2620. Return the value as key and the frequency of that value in <input> as value */
  2621. PHP_FUNCTION(array_count_values)
  2622. {
  2623. zval **input, /* Input array */
  2624. **entry; /* An entry in the input array */
  2625. zval **tmp;
  2626. HashTable *myht;
  2627. /* Get arguments and do error-checking */
  2628. if (ARG_COUNT(ht) != 1 || getParametersEx(1, &input) == FAILURE) {
  2629. WRONG_PARAM_COUNT;
  2630. }
  2631. if ((*input)->type != IS_ARRAY) {
  2632. zend_error(E_WARNING, "Argument to array_count_values() should be an array");
  2633. return;
  2634. }
  2635. /* Initialize return array */
  2636. array_init(return_value);
  2637. /* Go through input array and add values to the return array */
  2638. myht = (*input)->value.ht;
  2639. zend_hash_internal_pointer_reset(myht);
  2640. while (zend_hash_get_current_data(myht, (void **)&entry) == SUCCESS) {
  2641. if ((*entry)->type == IS_LONG) {
  2642. if (zend_hash_index_find(return_value->value.ht,
  2643. (*entry)->value.lval,
  2644. (void**)&tmp) == FAILURE) {
  2645. zval *data;
  2646. MAKE_STD_ZVAL(data);
  2647. data->type = IS_LONG;
  2648. data->value.lval = 1;
  2649. zend_hash_index_update(return_value->value.ht,(*entry)->value.lval, &data, sizeof(data), NULL);
  2650. } else {
  2651. (*tmp)->value.lval++;
  2652. }
  2653. } else if ((*entry)->type == IS_STRING) {
  2654. if (zend_hash_find(return_value->value.ht,
  2655. (*entry)->value.str.val,
  2656. (*entry)->value.str.len+1,
  2657. (void**)&tmp) == FAILURE) {
  2658. zval *data;
  2659. MAKE_STD_ZVAL(data);
  2660. data->type = IS_LONG;
  2661. data->value.lval = 1;
  2662. zend_hash_update(return_value->value.ht,(*entry)->value.str.val,(*entry)->value.str.len + 1, &data, sizeof(data), NULL);
  2663. } else {
  2664. (*tmp)->value.lval++;
  2665. }
  2666. } else {
  2667. zend_error(E_WARNING, "Can only count STRING and INTEGER values!");
  2668. }
  2669. zend_hash_move_forward(myht);
  2670. }
  2671. }
  2672. /* }}} */
  2673. /* {{{ proto array array_reverse(array input)
  2674. Return input as a new array with the order of the entries reversed */
  2675. PHP_FUNCTION(array_reverse)
  2676. {
  2677. zval **input, /* Input array */
  2678. **entry; /* An entry in the input array */
  2679. char *string_key;
  2680. ulong num_key;
  2681. /* Get arguments and do error-checking */
  2682. if (ARG_COUNT(ht) != 1 || getParametersEx(1, &input) == FAILURE) {
  2683. WRONG_PARAM_COUNT;
  2684. }
  2685. if ((*input)->type != IS_ARRAY) {
  2686. zend_error(E_WARNING, "Argument to array_reverse() should be an array");
  2687. return;
  2688. }
  2689. /* Initialize return array */
  2690. array_init(return_value);
  2691. zend_hash_internal_pointer_end((*input)->value.ht);
  2692. while(zend_hash_get_current_data((*input)->value.ht, (void **)&entry) == SUCCESS) {
  2693. (*entry)->refcount++;
  2694. switch (zend_hash_get_current_key((*input)->value.ht, &string_key, &num_key)) {
  2695. case HASH_KEY_IS_STRING:
  2696. zend_hash_update(return_value->value.ht, string_key, strlen(string_key)+1,
  2697. entry, sizeof(zval *), NULL);
  2698. efree(string_key);
  2699. break;
  2700. case HASH_KEY_IS_LONG:
  2701. zend_hash_next_index_insert(return_value->value.ht,
  2702. entry, sizeof(zval *), NULL);
  2703. break;
  2704. }
  2705. zend_hash_move_backwards((*input)->value.ht);
  2706. }
  2707. }
  2708. /* }}} */
  2709. /*
  2710. * Local variables:
  2711. * tab-width: 4
  2712. * c-basic-offset: 4
  2713. * End:
  2714. */