<?php

namespace VariableAnalysis\Lib;

class Constants {
	/**
	 *  Array of known pass-by-reference functions and the argument(s) which are passed
	 *  by reference, the arguments are numbered starting from 1 and an elipsis '...'
	 *  means all argument numbers after the previous should be considered pass-by-reference.
	 *
	 *  This does not need to cover all pass-by-reference arguments, only the
	 *  ones which can be passed an undefined variable (eg: `$matches` in
	 *  `preg_match`) and will define that variable.
	 *
	 *  @return array[]
	 */
	public static function getPassByReferenceFunctions() {
		return array(
			'__soapCall'                  => array( 5 ),
			'addFunction'                 => array( 3 ),
			'addTask'                     => array( 3 ),
			'addTaskBackground'           => array( 3 ),
			'addTaskHigh'                 => array( 3 ),
			'addTaskHighBackground'       => array( 3 ),
			'addTaskLow'                  => array( 3 ),
			'addTaskLowBackground'        => array( 3 ),
			'addTaskStatus'               => array( 2 ),
			'apc_dec'                     => array( 3 ),
			'apc_fetch'                   => array( 2 ),
			'apc_inc'                     => array( 3 ),
			'apcu_dec'                    => array( 3 ),
			'apcu_fetch'                  => array( 2 ),
			'apcu_inc'                    => array( 3 ),
			'areConfusable'               => array( 3 ),
			'arsort'                      => array( 1 ),
			'asort'                       => array( 1 ),
			'bindColumn'                  => array( 2 ),
			'bindParam'                   => array( 2 ),
			'bind_param'                  => array( 2, 3, '...' ),
			'bind_result'                 => array( 1, 2, '...' ),
			'call_user_method'            => array( 2 ),
			'call_user_method_array'      => array( 2 ),
			'curl_multi_exec'             => array( 2 ),
			'curl_multi_info_read'        => array( 2 ),
			'current'                     => array( 1 ),
			'dbplus_curr'                 => array( 2 ),
			'dbplus_first'                => array( 2 ),
			'dbplus_info'                 => array( 3 ),
			'dbplus_last'                 => array( 2 ),
			'dbplus_next'                 => array( 2 ),
			'dbplus_prev'                 => array( 2 ),
			'dbplus_tremove'              => array( 3 ),
			'dns_get_record'              => array( 3, 4 ),
			'domxml_open_file'            => array( 3 ),
			'domxml_open_mem'             => array( 3 ),
			'each'                        => array( 1 ),
			'enchant_dict_quick_check'    => array( 3 ),
			'end'                         => array( 1 ),
			'ereg'                        => array( 3 ),
			'eregi'                       => array( 3 ),
			'exec'                        => array( 2, 3 ),
			'exif_thumbnail'              => array( 1, 2, 3 ),
			'expect_expectl'              => array( 3 ),
			'extract'                     => array( 1 ),
			'filter'                      => array( 3 ),
			'flock'                       => array( 2, 3 ),
			'fscanf'                      => array( 2, 3, '...' ),
			'fsockopen'                   => array( 3, 4 ),
			'ftp_alloc'                   => array( 3 ),
			'get'                         => array( 2, 3 ),
			'getByKey'                    => array( 4 ),
			'getMulti'                    => array( 2 ),
			'getMultiByKey'               => array( 3 ),
			'getimagesize'                => array( 2 ),
			'getmxrr'                     => array( 2, 3 ),
			'gnupg_decryptverify'         => array( 3 ),
			'gnupg_verify'                => array( 4 ),
			'grapheme_extract'            => array( 5 ),
			'headers_sent'                => array( 1, 2 ),
			'http_build_url'              => array( 4 ),
			'http_get'                    => array( 3 ),
			'http_head'                   => array( 3 ),
			'http_negotiate_charset'      => array( 2 ),
			'http_negotiate_content_type' => array( 2 ),
			'http_negotiate_language'     => array( 2 ),
			'http_post_data'              => array( 4 ),
			'http_post_fields'            => array( 5 ),
			'http_put_data'               => array( 4 ),
			'http_put_file'               => array( 4 ),
			'http_put_stream'             => array( 4 ),
			'http_request'                => array( 5 ),
			'isSuspicious'                => array( 2 ),
			'is_callable'                 => array( 3 ),
			'key'                         => array( 1 ),
			'krsort'                      => array( 1 ),
			'ksort'                       => array( 1 ),
			'ldap_get_option'             => array( 3 ),
			'ldap_parse_reference'        => array( 3 ),
			'ldap_parse_result'           => array( 3, 4, 5, 6 ),
			'localtime'                   => array( 2 ),
			'm_completeauthorizations'    => array( 2 ),
			'maxdb_stmt_bind_param'       => array( 3, 4, '...' ),
			'maxdb_stmt_bind_result'      => array( 2, 3, '...' ),
			'mb_convert_variables'        => array( 3, 4, '...' ),
			'mb_parse_str'                => array( 2 ),
			'mqseries_back'               => array( 2, 3 ),
			'mqseries_begin'              => array( 3, 4 ),
			'mqseries_close'              => array( 4, 5 ),
			'mqseries_cmit'               => array( 2, 3 ),
			'mqseries_conn'               => array( 2, 3, 4 ),
			'mqseries_connx'              => array( 2, 3, 4, 5 ),
			'mqseries_disc'               => array( 2, 3 ),
			'mqseries_get'                => array( 3, 4, 5, 6, 7, 8, 9 ),
			'mqseries_inq'                => array( 6, 8, 9, 10 ),
			'mqseries_open'               => array( 2, 4, 5, 6 ),
			'mqseries_put'                => array( 3, 4, 6, 7 ),
			'mqseries_put1'               => array( 2, 3, 4, 6, 7 ),
			'mqseries_set'                => array( 9, 10 ),
			'msg_receive'                 => array( 3, 5, 8 ),
			'msg_send'                    => array( 6 ),
			'mssql_bind'                  => array( 3 ),
			'natcasesort'                 => array( 1 ),
			'natsort'                     => array( 1 ),
			'ncurses_color_content'       => array( 2, 3, 4 ),
			'ncurses_getmaxyx'            => array( 2, 3 ),
			'ncurses_getmouse'            => array( 1 ),
			'ncurses_getyx'               => array( 2, 3 ),
			'ncurses_instr'               => array( 1 ),
			'ncurses_mouse_trafo'         => array( 1, 2 ),
			'ncurses_mousemask'           => array( 2 ),
			'ncurses_pair_content'        => array( 2, 3 ),
			'ncurses_wmouse_trafo'        => array( 2, 3 ),
			'newt_button_bar'             => array( 1 ),
			'newt_form_run'               => array( 2 ),
			'newt_get_screen_size'        => array( 1, 2 ),
			'newt_grid_get_size'          => array( 2, 3 ),
			'newt_reflow_text'            => array( 5, 6 ),
			'newt_win_entries'            => array( 7 ),
			'newt_win_menu'               => array( 8 ),
			'next'                        => array( 1 ),
			'oci_bind_array_by_name'      => array( 3 ),
			'oci_bind_by_name'            => array( 3 ),
			'oci_define_by_name'          => array( 3 ),
			'oci_fetch_all'               => array( 2 ),
			'ocifetchinto'                => array( 2 ),
			'odbc_fetch_into'             => array( 2 ),
			'openssl_csr_export'          => array( 2 ),
			'openssl_csr_new'             => array( 2 ),
			'openssl_open'                => array( 2 ),
			'openssl_pkcs12_export'       => array( 2 ),
			'openssl_pkcs12_read'         => array( 2 ),
			'openssl_pkey_export'         => array( 2 ),
			'openssl_private_decrypt'     => array( 2 ),
			'openssl_private_encrypt'     => array( 2 ),
			'openssl_public_decrypt'      => array( 2 ),
			'openssl_public_encrypt'      => array( 2 ),
			'openssl_random_pseudo_bytes' => array( 2 ),
			'openssl_seal'                => array( 2, 3 ),
			'openssl_sign'                => array( 2 ),
			'openssl_x509_export'         => array( 2 ),
			'ovrimos_fetch_into'          => array( 2 ),
			'parse'                       => array( 2, 3 ),
			'parseCurrency'               => array( 2, 3 ),
			'parse_str'                   => array( 2 ),
			'parsekit_compile_file'       => array( 2 ),
			'parsekit_compile_string'     => array( 2 ),
			'passthru'                    => array( 2 ),
			'pcntl_sigprocmask'           => array( 3 ),
			'pcntl_sigtimedwait'          => array( 2 ),
			'pcntl_sigwaitinfo'           => array( 2 ),
			'pcntl_wait'                  => array( 1 ),
			'pcntl_waitpid'               => array( 2 ),
			'pfsockopen'                  => array( 3, 4 ),
			'php_check_syntax'            => array( 2 ),
			'poll'                        => array( 1, 2, 3 ),
			'preg_filter'                 => array( 5 ),
			'preg_match'                  => array( 3 ),
			'preg_match_all'              => array( 3 ),
			'preg_replace'                => array( 5 ),
			'preg_replace_callback'       => array( 5 ),
			'prev'                        => array( 1 ),
			'proc_open'                   => array( 3 ),
			'query'                       => array( 3 ),
			'queryExec'                   => array( 2 ),
			'reset'                       => array( 1 ),
			'rsort'                       => array( 1 ),
			'settype'                     => array( 1 ),
			'shuffle'                     => array( 1 ),
			'similar_text'                => array( 3 ),
			'socket_create_pair'          => array( 4 ),
			'socket_getpeername'          => array( 2, 3 ),
			'socket_getsockname'          => array( 2, 3 ),
			'socket_recv'                 => array( 2 ),
			'socket_recvfrom'             => array( 2, 5, 6 ),
			'socket_select'               => array( 1, 2, 3 ),
			'sort'                        => array( 1 ),
			'sortWithSortKeys'            => array( 1 ),
			'sqlite_exec'                 => array( 3 ),
			'sqlite_factory'              => array( 3 ),
			'sqlite_open'                 => array( 3 ),
			'sqlite_popen'                => array( 3 ),
			'sqlite_query'                => array( 4 ),
			'sqlite_unbuffered_query'     => array( 4 ),
			'sscanf'                      => array( 3, '...' ),
			'str_ireplace'                => array( 4 ),
			'str_replace'                 => array( 4 ),
			'stream_open'                 => array( 4 ),
			'stream_select'               => array( 1, 2, 3 ),
			'stream_socket_accept'        => array( 3 ),
			'stream_socket_client'        => array( 2, 3 ),
			'stream_socket_recvfrom'      => array( 4 ),
			'stream_socket_server'        => array( 2, 3 ),
			'system'                      => array( 2 ),
			'uasort'                      => array( 1 ),
			'uksort'                      => array( 1 ),
			'unbufferedQuery'             => array( 3 ),
			'usort'                       => array( 1 ),
			'wincache_ucache_dec'         => array( 3 ),
			'wincache_ucache_get'         => array( 2 ),
			'wincache_ucache_inc'         => array( 3 ),
			'xdiff_string_merge3'         => array( 4 ),
			'xdiff_string_patch'          => array( 4 ),
			'xml_parse_into_struct'       => array( 3, 4 ),
			'xml_set_object'              => array( 2 ),
			'xmlrpc_decode_request'       => array( 2 ),
			'xmlrpc_set_type'             => array( 1 ),
			'xslt_set_object'             => array( 2 ),
			'yaml_parse'                  => array( 3 ),
			'yaml_parse_file'             => array( 3 ),
			'yaml_parse_url'              => array( 3 ),
			'yaz_ccl_parse'               => array( 3 ),
			'yaz_hits'                    => array( 2 ),
			'yaz_scan_result'             => array( 2 ),
			'yaz_wait'                    => array( 1 ),
		);
	}

	/**
	 * @return array[]
	 */
	public static function getWordPressPassByReferenceFunctions() {
		return array(
			'wp_parse_str' => array( 2 ),
			'wp_cache_get' => array( 4 ),
		);
	}

	/**
	 * A regexp for matching variable names in double-quoted strings.
	 *
	 * @return string
	 */
	public static function getDoubleQuotedVarRegexp() {
		return '|(?<!\\\\)(?:\\\\{2})*\${?([a-zA-Z0-9_]+)}?|';
	}
}
