php/sigfiles/generate.php
author Tomas Mysik <tmysik@netbeans.org>
Mon, 12 Jun 2017 09:13:11 +0200
changeset 6391 640ddcff4333
parent 6390 73661dbdafd6
permissions -rw-r--r--
Return blacklisted methods back

No blacklisted methods right now but keep the code for possible future usage.
tmysik@6020
     1
<?php
tmysik@6020
     2
/**
tmysik@6020
     3
 * This script can be used for generating PHP model for PDT.
tmysik@6020
     4
 * It builds PHP functions according to the loaded extensions in running PHP,
tmysik@6020
     5
 * using complementary information gathered from PHP.net documentation
tmysik@6020
     6
 *
tmysik@6020
     7
 * @author Michael Spector <michael@zend.com>
tmysik@6020
     8
 */
tmysik@6020
     9
tmysik@6020
    10
define("BRANCH_DIR", ""); // can be e.g. "/trunk" (do not forget slash!)
tmysik@6020
    11
define("DOC_URL", "./html/");      // PHP documentation, separate HTML files
tmysik@6020
    12
if (!is_dir(DOC_URL)) {
tmysik@6020
    13
    die('Incorrect directory for separated HTML files ("./html/" expected)!');
tmysik@6020
    14
}
tmysik@6020
    15
tmysik@6020
    16
if (version_compare(phpversion(), "5.0.0") < 0) {
tmysik@6020
    17
	die ("This script requires PHP 5.0.0 or higher!\n");
tmysik@6020
    18
}
tmysik@6020
    19
tmysik@6020
    20
$splitFiles = true;
tmysik@6020
    21
$phpdocDir = null;
tmysik@6020
    22
tmysik@6325
    23
$phpDir = "php";
tmysik@6388
    24
$lang = "en";
tmysik@6020
    25
tmysik@6020
    26
// Parse arguments:
tmysik@6020
    27
$argv = $_SERVER["argv"];
tmysik@6020
    28
$argv0 = array_shift ($argv);
tmysik@6020
    29
for ($i = 0; $i < count($argv); ++$i) {
tmysik@6020
    30
	switch ($argv[$i]) {
tmysik@6020
    31
		case "-nosplit":
tmysik@6020
    32
			$splitFiles = false;
tmysik@6020
    33
			break;
tmysik@6020
    34
tmysik@6388
    35
		case "-split":
tmysik@6388
    36
			$splitFiles = true;
tmysik@6388
    37
			break;
tmysik@6388
    38
tmysik@6020
    39
		case "-help":
tmysik@6020
    40
			show_help();
tmysik@6020
    41
			break;
tmysik@6020
    42
tmysik@6388
    43
		case "-lang":
tmysik@6388
    44
			++$i;
tmysik@6388
    45
			$lang = $argv[$i];
tmysik@6388
    46
                        if ($lang[0] === '-') {
tmysik@6388
    47
				show_message("Invalid arg for -lang: " . $argv[$i]);
tmysik@6388
    48
				show_help();
tmysik@6388
    49
                        }
tmysik@6388
    50
			break;
tmysik@6388
    51
tmysik@6388
    52
		case "-output":
tmysik@6388
    53
			++$i;
tmysik@6388
    54
			$phpDir = $argv[$i];
tmysik@6388
    55
                        if ($phpDir[0] === '-') {
tmysik@6388
    56
				show_message("Invalid arg for -output: " . $argv[$i]);
tmysik@6388
    57
				show_help();
tmysik@6388
    58
                        }
tmysik@6388
    59
			break;
tmysik@6388
    60
tmysik@6020
    61
		default:
tmysik@6020
    62
			$phpdocDir = $argv[$i];
tmysik@6020
    63
	}
tmysik@6020
    64
}
tmysik@6020
    65
tmysik@6020
    66
if (!$phpdocDir) {
tmysik@6020
    67
	show_help();
tmysik@6020
    68
}
tmysik@6020
    69
tmysik@6020
    70
/***************** REMOVED FUNCTIONS (START) *************************/
tmysik@6020
    71
tmysik@6020
    72
// add these functions to $removedFunctions!
tmysik@6020
    73
tmysik@6020
    74
if (!function_exists('ob_iconv_handler')) {
tmysik@6020
    75
    function ob_iconv_handler($contents, $status) {}
tmysik@6020
    76
}
tmysik@6020
    77
if (!function_exists('ob_tidyhandler')) {
tmysik@6020
    78
    function ob_tidyhandler($input, $mode = 0) {}
tmysik@6020
    79
}
tmysik@6020
    80
if (!function_exists('session_register')) {
tmysik@6020
    81
    function session_register($name, $_ = null) {}
tmysik@6020
    82
}
tmysik@6020
    83
if (!function_exists('session_unregister')) {
tmysik@6020
    84
    function session_unregister($name) {}
tmysik@6020
    85
}
tmysik@6020
    86
if (!function_exists('session_is_registered')) {
tmysik@6020
    87
    function session_is_registered($name) {}
tmysik@6020
    88
}
tmysik@6020
    89
if (!function_exists('chroot')) {
tmysik@6020
    90
    function chroot($directory) {}
tmysik@6020
    91
}
tmysik@6020
    92
tmysik@6020
    93
/***************** REMOVED FUNCTIONS (END) *************************/
tmysik@6020
    94
tmysik@6388
    95
$entities = parse_entities($phpdocDir, $lang);
tmysik@6020
    96
$extensions = get_loaded_extensions();
tmysik@6388
    97
$functionsDoc = parse_phpdoc_functions ($phpdocDir, $extensions, $lang);
tmysik@6388
    98
$fieldsDoc = parse_phpdoc_fields ($phpdocDir, $extensions, $lang);
tmysik@6388
    99
$classesDoc = parse_phpdoc_classes ($phpdocDir, $extensions, $lang);
tmysik@6020
   100
$constantsDoc = parse_phpdoc_constants ($phpdocDir);
tmysik@6020
   101
$removedFunctions = array(
tmysik@6020
   102
    'ob_iconv_handler',
tmysik@6020
   103
    'ob_tidyhandler',
tmysik@6020
   104
    'session_register',
tmysik@6020
   105
    'session_unregister',
tmysik@6020
   106
    'session_is_registered',
tmysik@6020
   107
    'chroot',
tmysik@6020
   108
);
tmysik@6020
   109
$functionBlackList = array(
tmysik@6020
   110
    'oci_lob_save' => 1,
tmysik@6020
   111
    'oci_lob_import' => 1,
tmysik@6020
   112
    'oci_lob_size' => 1,
tmysik@6020
   113
    'oci_lob_load' => 1,
tmysik@6020
   114
    'oci_lob_read' => 1,
tmysik@6020
   115
    'oci_lob_eof' => 1,
tmysik@6020
   116
    'oci_lob_tell' => 1,
tmysik@6020
   117
    'oci_lob_truncate' => 1,
tmysik@6020
   118
    'oci_lob_erase' => 1,
tmysik@6020
   119
    'oci_lob_flush' => 1,
tmysik@6020
   120
    'ocisetbufferinglob' => 1,
tmysik@6020
   121
    'ocigetbufferinglob' => 1,
tmysik@6020
   122
    'oci_lob_rewind' => 1,
tmysik@6020
   123
    'oci_lob_write' => 1,
tmysik@6020
   124
    'oci_lob_append' => 1,
tmysik@6020
   125
    'oci_lob_export' => 1,
tmysik@6020
   126
    'oci_lob_seek' => 1,
tmysik@6020
   127
    'oci_free_collection' => 1,
tmysik@6020
   128
    'oci_collection_append' => 1,
tmysik@6020
   129
    'oci_collection_element_get' => 1,
tmysik@6020
   130
    'oci_collection_element_assign' => 1,
tmysik@6020
   131
    'oci_collection_size' => 1,
tmysik@6020
   132
    'oci_collection_max' => 1,
tmysik@6020
   133
    'oci_collection_trim' => 1,
tmysik@6020
   134
    'oci_collection_assign' => 1,
tmysik@6020
   135
);
tmysik@6391
   136
$methodBlackList = array(
tmysik@6391
   137
);
tmysik@6100
   138
$preferHtmlProperties = array(
tmysik@6100
   139
    'mysqli',
tmysik@6100
   140
);
tmysik@6020
   141
tmysik@6020
   142
$processedFunctions = $functionBlackList;
tmysik@6020
   143
$processedClasses = array();
tmysik@6020
   144
$processedConstants = array();
tmysik@6020
   145
tmysik@6020
   146
@mkdir ($phpDir);
tmysik@6020
   147
tmysik@6020
   148
if (!$splitFiles) {
tmysik@6020
   149
	begin_file_output();
tmysik@6020
   150
}
tmysik@6020
   151
foreach ($extensions as $extName) {
tmysik@6020
   152
	if ($splitFiles) {
tmysik@6020
   153
		begin_file_output();
tmysik@6020
   154
	}
tmysik@6020
   155
	print_extension (new ReflectionExtension ($extName));
tmysik@6020
   156
	if ($splitFiles) {
tmysik@6020
   157
		finish_file_output("{$phpDir}/{$extName}.php");
tmysik@6020
   158
	}
tmysik@6020
   159
}
tmysik@6020
   160
tmysik@6020
   161
if ($splitFiles) {
tmysik@6020
   162
	begin_file_output();
tmysik@6020
   163
}
tmysik@6020
   164
$intFunctions = get_defined_functions();
tmysik@6020
   165
foreach ($intFunctions["internal"] as $intFunction) {
tmysik@6020
   166
	if (!@$processedFunctions[strtolower($intFunction)]) {
tmysik@6020
   167
		print_function (new ReflectionFunction ($intFunction));
tmysik@6020
   168
	}
tmysik@6020
   169
}
tmysik@6020
   170
tmysik@6020
   171
$intClasses = array_merge (get_declared_classes(), get_declared_interfaces(), get_declared_traits());
tmysik@6020
   172
foreach ($intClasses as $intClass) {
tmysik@6060
   173
    if (strpos($intClass, 'NetBeans_') === 0) {
tmysik@6060
   174
        continue;
tmysik@6060
   175
    }
tmysik@6020
   176
	if (!@$processedClasses[strtolower($intClass)]) {
tmysik@6020
   177
		print_class (new ReflectionClass ($intClass));
tmysik@6020
   178
	}
tmysik@6020
   179
}
tmysik@6020
   180
tmysik@6020
   181
print "\n";
tmysik@6020
   182
$constants = get_defined_constants(true);
tmysik@6020
   183
$intConstants = isset($constants["internal"]) ? $constants["internal"] : array();
tmysik@6020
   184
// add magic constants:
tmysik@6020
   185
$intConstants['__FILE__'] = null;
tmysik@6020
   186
$intConstants['__LINE__'] = null;
tmysik@6020
   187
$intConstants['__CLASS__'] = null;
tmysik@6020
   188
$intConstants['__FUNCTION__'] = null;
tmysik@6020
   189
$intConstants['__METHOD__'] = null;
tmysik@6048
   190
$intConstants['__TRAIT__'] = null;
tmysik@6020
   191
if (version_compare(phpversion(), "5.3.0") >= 0) {
tmysik@6020
   192
	$intConstants['__DIR__'] = null;
tmysik@6020
   193
	$intConstants['__NAMESPACE__'] = null;
tmysik@6020
   194
}
tmysik@6020
   195
foreach ($intConstants as $name => $value) {
tmysik@6020
   196
	if (!@$processedConstants[$name]) {
tmysik@6020
   197
		print_constant ($name, $value);
tmysik@6020
   198
	}
tmysik@6020
   199
}
tmysik@6020
   200
tmysik@6020
   201
finish_file_output("{$phpDir}/basic.php");
tmysik@6020
   202
tmysik@6020
   203
// removed functions
tmysik@6020
   204
if ($splitFiles) {
tmysik@6020
   205
    begin_file_output();
tmysik@6020
   206
}
tmysik@6020
   207
foreach ($removedFunctions as $removedFunction) {
tmysik@6020
   208
	if (!@$processedFunctions[strtolower($removedFunction)]) {
tmysik@6020
   209
		print_function (new ReflectionFunction ($removedFunction));
tmysik@6020
   210
	}
tmysik@6020
   211
}
tmysik@6020
   212
if ($splitFiles) {
tmysik@6020
   213
    finish_file_output("{$phpDir}/removed.php");
tmysik@6020
   214
}
tmysik@6020
   215
tmysik@6020
   216
tmysik@6020
   217
// Create .list file
tmysik@6020
   218
$fp = fopen ("{$phpDir}/.list", "w");
tmysik@6020
   219
foreach (glob("{$phpDir}/*.php") as $f) {
tmysik@6020
   220
	fwrite ($fp, basename($f));
tmysik@6020
   221
	fwrite ($fp, "\n");
tmysik@6020
   222
}
tmysik@6020
   223
fclose($fp);
tmysik@6020
   224
tmysik@6020
   225
tmysik@6020
   226
function findVerInfo($file)
tmysik@6020
   227
 {
tmysik@6020
   228
    $url = DOC_URL.$file.".html";
tmysik@6020
   229
    $search_for = '<p class="verinfo">';
tmysik@6020
   230
    //echo "Reading $url :\n";
tmysik@6020
   231
tmysik@6020
   232
    if (!is_file($url)) {
tmysik@6020
   233
        return;
tmysik@6020
   234
    }
tmysik@6020
   235
tmysik@6020
   236
    $file_contents = file_get_contents($url);
tmysik@6020
   237
tmysik@6020
   238
    $start_pos = strpos($file_contents, $search_for);
tmysik@6020
   239
tmysik@6020
   240
    if ($start_pos !== 0) {
tmysik@6020
   241
       $start_pos += strlen($search_for);
tmysik@6020
   242
       $end_pos = strpos($file_contents, '</p>', $start_pos);
tmysik@6020
   243
tmysik@6020
   244
       if ($end_pos !== 0) {
tmysik@6020
   245
          $verinfo = substr($file_contents, $start_pos, $end_pos - $start_pos);
tmysik@6020
   246
          //echo "Ver. info: $verinfo\n";
tmysik@6020
   247
          return $verinfo;
tmysik@6020
   248
       }
tmysik@6020
   249
    }
tmysik@6020
   250
 }
tmysik@6020
   251
tmysik@6020
   252
// === Functions ===
tmysik@6020
   253
/**
tmysik@6020
   254
 * Makes generic key from given function name
tmysik@6020
   255
 * @param name string Function name
tmysik@6020
   256
 * @return string generic key
tmysik@6020
   257
 */
tmysik@6020
   258
function make_funckey_from_str ($name) {
tmysik@6020
   259
	$name = str_replace ("->", "::", $name);
tmysik@6020
   260
	$name = str_replace ("()", "", $name);
tmysik@6020
   261
	$name = strtolower ($name);
tmysik@6020
   262
	return $name;
tmysik@6020
   263
}
tmysik@6020
   264
tmysik@6020
   265
/**
tmysik@6020
   266
 * Replaces all invalid charaters with '_' in PHP identifier
tmysik@6020
   267
 * @param name PHP identifier
tmysik@6020
   268
 * @return string PHP identifier with stripped invalid characters
tmysik@6020
   269
 */
tmysik@6020
   270
function clean_php_identifier ($name) {
tmysik@6020
   271
	$name = preg_replace('/[^\$\w\_]+/', '_', $name);
tmysik@6020
   272
	return $name;
tmysik@6020
   273
}
tmysik@6020
   274
tmysik@6020
   275
function clean_php_value($type) {
tmysik@6020
   276
    $type = trim($type);
tmysik@6020
   277
    $type = str_replace("&null;", "null", $type);
tmysik@6202
   278
    $type = str_replace("&true;", "true", $type);
tmysik@6202
   279
    $type = str_replace("&false;", "false", $type);
tmysik@6202
   280
    $type = str_replace("&quot;", "", $type);
tmysik@6020
   281
    $type = strip_tags($type);
tmysik@6020
   282
    return $type;
tmysik@6020
   283
}
tmysik@6020
   284
tmysik@6020
   285
/**
tmysik@6020
   286
 * Makes generic key from given function reference
tmysik@6020
   287
 * @param name ReflectionMethod function reference
tmysik@6020
   288
 * @return string generic key
tmysik@6020
   289
 */
tmysik@6020
   290
function make_funckey_from_ref ($ref) {
tmysik@6020
   291
	if ($ref instanceof ReflectionMethod) {
tmysik@6020
   292
		$funckey = make_classmember_ref($ref->getDeclaringClass()->getName(), $ref->getName());
tmysik@6020
   293
	} else {
tmysik@6020
   294
		$funckey = strtolower($ref->getName());
tmysik@6020
   295
	}
tmysik@6020
   296
	return $funckey;
tmysik@6020
   297
}
tmysik@6020
   298
function make_property_from_ref ($ref) {
tmysik@6020
   299
	if ($ref instanceof ReflectionProperty) {
tmysik@6020
   300
		$funckey = make_classmember_ref($ref->getDeclaringClass()->getName(), $ref->getName());
tmysik@6020
   301
	} else {
tmysik@6020
   302
		throw new Exception("Unexpected type: ".gettype($ref));
tmysik@6020
   303
	}
tmysik@6020
   304
	return $funckey;
tmysik@6020
   305
}
tmysik@6020
   306
tmysik@6020
   307
function make_classmember_ref ($className, $memberName) {
tmysik@6020
   308
	return strtolower($className)."::".strtolower($memberName);
tmysik@6020
   309
}
tmysik@6020
   310
tmysik@6020
   311
tmysik@6020
   312
/**
tmysik@6020
   313
 * Parses PHP documentation
tmysik@6020
   314
 * @param phpdocDir string PHP.net documentation directory
tmysik@6020
   315
 * @return array Function information gathered from the PHP.net documentation by parsing XML files
tmysik@6020
   316
 */
tmysik@6388
   317
function parse_phpdoc_functions ($phpdocDir, $extensions, $lang) {
tmysik@6020
   318
	$xml_files = array_merge (
tmysik@6388
   319
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/*/functions/*.xml"),
tmysik@6388
   320
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/language/predefined/*/*.xml"),
tmysik@6388
   321
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/*/functions/*/*.xml")
tmysik@6020
   322
	);
tmysik@6020
   323
	foreach ($extensions as $extName) {
tmysik@6020
   324
		$extName = strtolower($extName);
tmysik@6388
   325
		$globPattern = "{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/{$extName}/*/*.xml";
tmysik@6020
   326
		$xml_files = array_merge (
tmysik@6020
   327
			$xml_files,
tmysik@6020
   328
			glob ($globPattern)
tmysik@6020
   329
		);
tmysik@6020
   330
	}
tmysik@6020
   331
    $functionsDoc = array();
tmysik@6020
   332
	foreach ($xml_files as $xml_file) {
tmysik@6020
   333
		$xml = file_get_contents ($xml_file);
tmysik@6020
   334
tmysik@6058
   335
		if (preg_match ('@<refentry.*?xml:id=["\'](.*?)["\'].*?>.*?<refname>(.*?)</refname>\s*(?:<refname>(.*?)</refname>)?.*?<refpurpose>(.*?)</refpurpose>@s', $xml, $match)) {
tmysik@6058
   336
            $id = $match[1];
tmysik@6058
   337
            $refnames = array($match[2], $match[3]);
tmysik@6058
   338
            $phpdoc = $match[4];
tmysik@6058
   339
            foreach ($refnames as $refname) {
tmysik@6058
   340
                $refname = trim($refname);
tmysik@6058
   341
                if ($refname == '') {
tmysik@6058
   342
                    continue;
tmysik@6058
   343
                }
tmysik@6058
   344
                $refname = make_funckey_from_str ($refname);
tmysik@6058
   345
                if (array_key_exists($refname, $functionsDoc)) {
tmysik@6058
   346
                    // already there
tmysik@6058
   347
                    continue;
tmysik@6058
   348
                }
tmysik@6058
   349
                $functionsDoc[$refname] = array();
tmysik@6058
   350
                $functionsDoc[$refname]['id'] = $id;
tmysik@6058
   351
                $functionsDoc[$refname]['quickref'] = xml_to_phpdoc($phpdoc);
tmysik@6058
   352
                $functionsDoc[$refname]['deprecated'] = strpos($xml_file, "/oldaliases/") !== false;
tmysik@6020
   353
tmysik@6058
   354
                if (preg_match ('@<refsect1\s+role=["\']description["\']>(.*?)</refsect1>@s', $xml, $match)) {
tmysik@6058
   355
                    $description = $match[1];
tmysik@6058
   356
                    $function_alias = null;
tmysik@6058
   357
                    $parameters = null;
tmysik@6058
   358
                    $has_object_style = false;
tmysik@6058
   359
                    if (preg_match ('@^(.*?)<classsynopsis>.*?<classname>(.*)</classname>.*?<methodsynopsis>.*?<type>(.*?)</type>.*?<methodname>(.*?)</methodname>(.*?)</methodsynopsis>.*?</classsynopsis>(.*)$@s', $description, $match)) {
tmysik@6058
   360
                        $functionsDoc[$refname]['classname'] = trim($match[2]);
tmysik@6058
   361
                        $functionsDoc[$refname]['returntype'] = trim($match[3]);
tmysik@6058
   362
                        $functionsDoc[$refname]['methodname'] = trim($match[4]);
tmysik@6058
   363
                        $parameters = $match[5];
tmysik@6058
   364
                        $description = $match[1].$match[6];
tmysik@6058
   365
                        $has_object_style = true;
tmysik@6058
   366
                    }
tmysik@6058
   367
                    $methodsynopsis = null;
tmysik@6058
   368
                    if ($refname == 'number_format') {
tmysik@6058
   369
                        $methodsynopsis = preg_match_all ('@<methodsynopsis>.*?<type>(.*?)</type>.*?<methodname>(.*?)</methodname>(.*?)</methodsynopsis>@s', $description, $tmp);
tmysik@6058
   370
                        $match = array();
tmysik@6058
   371
                        foreach ($tmp as $key => $val) {
tmysik@6058
   372
                            $match[$key] = $val[count($val) - 1];
tmysik@6058
   373
                        }
tmysik@6058
   374
                    } else {
tmysik@6058
   375
                        if (strpos($refname, '::') !== false) {
tmysik@6058
   376
                            $methodsynopsis = preg_match ('@<methodsynopsis role="oop">.*?(?:<type>(.*?)</type>.*?)?<methodname>(.*?)</methodname>(.*?)</methodsynopsis>@s', $description, $match);
tmysik@6058
   377
                        }
tmysik@6058
   378
                        if (!$methodsynopsis) {
tmysik@6198
   379
                            $methodsynopsis = preg_match ('@<methodsynopsis>.*?(?:<type>(.*?)</type>.*?)?<methodname>(.*?)</methodname>(.*?)</methodsynopsis>@s', $description, $match);
tmysik@6197
   380
                        }
tmysik@6197
   381
                        if (!$methodsynopsis) {
tmysik@6198
   382
                            $methodsynopsis = preg_match ('@<constructorsynopsis>.*?(?:<type>(.*?)</type>.*?)?<methodname>(.*?)</methodname>(.*?)</constructorsynopsis>@s', $description, $match);
tmysik@6058
   383
                        }
tmysik@6058
   384
                    }
tmysik@6058
   385
                    if ($methodsynopsis) {
tmysik@6058
   386
                        if ($has_object_style && make_funckey_from_str($match[2]) != $refname) {
tmysik@6058
   387
                            $function_alias = trim($match[2]);
tmysik@6058
   388
                        } else {
tmysik@6058
   389
                            $functionsDoc[$refname]['returntype'] = trim(str_replace('-', '_', $match[1])); // e.g. OCI-Collection -> OCI_Collection
tmysik@6058
   390
                            $functionsDoc[$refname]['methodname'] = trim($match[2]);
tmysik@6058
   391
                                                    $parameters = $match[3];
tmysik@6058
   392
                        }
tmysik@6058
   393
                    }
tmysik@6058
   394
                    if ($parameters) {
tmysik@6058
   395
                        if (preg_match_all ('@<methodparam\s*(.*?)>.*?<type>(.*?)</type>.*?<parameter\s*(.*?)>(.*?)</parameter>(?:<initializer>(.+?)</initializer>)?.*?</methodparam>@s', $parameters, $match)) {
tmysik@6058
   396
                            for ($i = 0; $i < count($match[0]); ++$i) {
tmysik@6058
   397
                                $parameter = array (
tmysik@6058
   398
                                    'type' => trim(str_replace('-', '_', $match[2][$i])), // e.g. OCI-Collection -> OCI_Collection
tmysik@6058
   399
                                    'name' => clean_php_identifier(trim($match[4][$i])),
tmysik@6058
   400
                                );
tmysik@6058
   401
                                if (preg_match ('@choice=[\'"]opt[\'"]@', $match[1][$i])) {
tmysik@6058
   402
                                    $parameter['isoptional'] = true;
tmysik@6020
   403
                                }
tmysik@6058
   404
                                if (preg_match ('@role=[\'"]reference[\'"]@', $match[3][$i])) {
tmysik@6058
   405
                                    $parameter['isreference'] = true;
tmysik@6058
   406
                                }
tmysik@6058
   407
                                if (@strlen(trim($match[5][$i]))) {
tmysik@6198
   408
                                    $def = $match[5][$i];
tmysik@6198
   409
                                    if ($def == '"\"') {
tmysik@6198
   410
                                        $def = '"\\\\"';
tmysik@6198
   411
                                    }
tmysik@6198
   412
                                    $parameter['defaultvalue'] = clean_php_value($def);
tmysik@6058
   413
                                                                    $parameter['isoptional'] = true;
tmysik@6058
   414
                                }
tmysik@6058
   415
                                $functionsDoc[$refname]['parameters'][] = $parameter;
tmysik@6020
   416
                            }
tmysik@6020
   417
                        }
tmysik@6020
   418
                    }
tmysik@6020
   419
                }
tmysik@6058
   420
                if (preg_match ('@<refsect1\s+role=["\']parameters["\']>(.*?)</refsect1>@s', $xml, $match)) {
tmysik@6058
   421
                    $parameters = $match[1];
tmysik@6058
   422
                    if (preg_match_all('@<varlistentry\s*.*?>.*?<parameter>(.*?)</parameter>.*?<listitem\s*.*?>(.*?)</listitem>.*?</varlistentry>@s', $parameters, $match)) {
tmysik@6058
   423
                        for ($i = 0; $i < count($match[0]); $i++) {
tmysik@6058
   424
                            for ($j = 0; $j < count(@$functionsDoc[$refname]['parameters']); $j++) {
tmysik@6058
   425
                                if (clean_php_identifier(trim($match[1][$i])) == $functionsDoc[$refname]['parameters'][$j]['name']) {
tmysik@6058
   426
                                    $functionsDoc[$refname]['parameters'][$j]['paramdoc'] = xml_to_phpdoc ($match[2][$i]);
tmysik@6058
   427
                                    break;
tmysik@6058
   428
                                }
tmysik@6058
   429
                            }
tmysik@6058
   430
                        }
tmysik@6058
   431
                    }
tmysik@6058
   432
                }
tmysik@6058
   433
                if (preg_match ('@<refsect1\s+role=["\']returnvalues["\']>(.*?)</refsect1>@s', $xml, $match)) {
tmysik@6058
   434
                    $returnvalues = $match[1];
tmysik@6058
   435
                    if (preg_match ('@<para>\s*(.*)</para>?@s', $returnvalues, $match)) {
tmysik@6058
   436
                        $functionsDoc[$refname]['returndoc'] = preg_replace("@^Returns @", "", xml_to_phpdoc ($match[1]));
tmysik@6058
   437
                    }
tmysik@6058
   438
                }
tmysik@6020
   439
tmysik@6058
   440
                // Create information for function alias
tmysik@6058
   441
                if ($function_alias) {
tmysik@6058
   442
                    $functionsDoc[$function_alias] = $functionsDoc[$refname];
tmysik@6058
   443
                }
tmysik@6058
   444
            }
tmysik@6020
   445
		}
tmysik@6020
   446
	}
tmysik@6020
   447
	return $functionsDoc;
tmysik@6020
   448
}
tmysik@6020
   449
tmysik@6020
   450
/**
tmysik@6020
   451
 * Parses PHP documentation
tmysik@6020
   452
 * @param phpdocDir string PHP.net documentation directory
tmysik@6020
   453
 * @return array Function information gathered from the PHP.net documentation by parsing XML files
tmysik@6020
   454
 */
tmysik@6388
   455
function parse_phpdoc_fields ($phpdocDir, $extensions, $lang) {
tmysik@6020
   456
	$xml_files = array();
tmysik@6020
   457
	foreach ($extensions as $extName) {
tmysik@6020
   458
		$extName = strtolower($extName);
tmysik@6020
   459
tmysik@6020
   460
		$xml_files = array_merge (
tmysik@6020
   461
			$xml_files,
tmysik@6388
   462
			glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/{$extName}/*.xml"),
tmysik@6388
   463
                        glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/{$extName}/*/*.xml")
tmysik@6020
   464
		);
tmysik@6020
   465
	}
tmysik@6020
   466
        foreach ($xml_files as $xml_file) {
tmysik@6020
   467
            $xml = file_get_contents($xml_file);
tmysik@6020
   468
            if (preg_match('@<classsynopsisinfo>.*?<classname>(.*)</classname>.*?</classsynopsisinfo>@s', $xml, $matchOffset, PREG_OFFSET_CAPTURE)) {
tmysik@6020
   469
                $classname = $matchOffset[1][0];
tmysik@6020
   470
                if (preg_match_all("@<fieldsynopsis>.*?<type>(.*?)</type>.*?<varname.*?>(.*?)</varname>@s", $xml, $matchOffset,null,$matchOffset[1][1])) {
tmysik@6020
   471
                    for ($index = 0; $index < count($matchOffset[2]); $index++) {
tmysik@6020
   472
                        $name = $matchOffset[2][$index];
tmysik@6020
   473
                        $type= $matchOffset[1][$index];
tmysik@6020
   474
                        $exploded = explode("::", $name);
tmysik@6020
   475
                        if (count($exploded) > 1) {
tmysik@6020
   476
                            $name = $exploded[1];
tmysik@6020
   477
                        }
tmysik@6020
   478
                        $reference = make_classmember_ref($classname, $name);
tmysik@6020
   479
                        $fieldsDoc[$reference]['field'] = $name;
tmysik@6020
   480
                        $fieldsDoc[$reference]['type'] = $type;
tmysik@6020
   481
                    }
tmysik@6020
   482
                }
tmysik@6020
   483
            } else {
tmysik@6020
   484
                if (preg_match('@<classsynopsis>.*?<classname>(.*)</classname>.*?<fieldsynopsis>.*?<type>(.*?)</type>.*?<varname.*?>(.*?)</varname>.*?</classsynopsis>@s', $xml, $match)) {
tmysik@6020
   485
                    $reference = make_classmember_ref($match[1], $match[3]);
tmysik@6020
   486
                    $fieldsDoc[$reference]['field'] = $match[3];
tmysik@6020
   487
                    $fieldsDoc[$reference]['type'] = $match[2];
tmysik@6020
   488
                    //$fieldsDoc[$refname]['quickref'] = trim($match[3]);
tmysik@6020
   489
                }
tmysik@6020
   490
            }
tmysik@6020
   491
tmysik@6020
   492
        }
tmysik@6020
   493
        if (isset($fieldsDoc)) {
tmysik@6020
   494
            return $fieldsDoc;
tmysik@6020
   495
        }
tmysik@6020
   496
        return array();
tmysik@6020
   497
}
tmysik@6020
   498
tmysik@6020
   499
/**
tmysik@6020
   500
 * Parses PHP documentation
tmysik@6020
   501
 * @param phpdocDir string PHP.net documentation directory
tmysik@6020
   502
 * @return array Class information gathered from the PHP.net documentation by parsing XML files
tmysik@6020
   503
 */
tmysik@6388
   504
function parse_phpdoc_classes ($phpdocDir, $extensions, $lang) {
tmysik@6020
   505
	$xml_files = array_merge (
tmysik@6388
   506
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/*/reference.xml"),
tmysik@6388
   507
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/*/classes.xml"),
tmysik@6388
   508
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/language/*/*.xml"),
tmysik@6388
   509
		glob ("{$phpdocDir}/{$lang}" . BRANCH_DIR . "/language/*.xml")
tmysik@6020
   510
	);
tmysik@6020
   511
	foreach ($extensions as $extName) {
tmysik@6020
   512
		$extName = strtolower($extName);
tmysik@6388
   513
		$globPattern = "{$phpdocDir}/{$lang}" . BRANCH_DIR . "/reference/{$extName}/*.xml";
tmysik@6020
   514
		$xml_files = array_merge (
tmysik@6020
   515
			$xml_files,
tmysik@6020
   516
			glob ($globPattern)
tmysik@6020
   517
		);
tmysik@6020
   518
	}
tmysik@6020
   519
tmysik@6020
   520
    $classesDoc = array();
tmysik@6020
   521
	foreach ($xml_files as $xml_file) {
tmysik@6020
   522
		$xml = file_get_contents ($xml_file);
tmysik@6020
   523
		if (preg_match ('@xml:id=["\'](.*?)["\']@', $xml, $match)) {
tmysik@6020
   524
			$id = $match[1];
tmysik@6020
   525
			$prefixId = substr($id, 0, strlen("class."));
tmysik@6020
   526
			$clsNamePattern = ($prefixId === "class.") ?
tmysik@6020
   527
			'@<ooclass><classname>(.*?)</classname></ooclass>@' :
tmysik@6020
   528
			'@<title><classname>(.*?)</classname></title>@';
tmysik@6020
   529
			if (preg_match_all ($clsNamePattern, $xml, $match)) {
tmysik@6020
   530
				for ($i = 0; $i < count($match[0]); ++$i) {
tmysik@6020
   531
					$class = $match[1][$i];
tmysik@6020
   532
					$refname = strtolower ($class);
tmysik@6020
   533
					$classesDoc[$refname]['id'] = $id;
tmysik@6020
   534
					$classesDoc[$refname]['name'] = $class;
tmysik@6020
   535
					$offsetPattern = ($prefixId === "class.") ?
tmysik@6020
   536
						"@xml:id=[\"'](.*?)\.intro[\"']@i" :
tmysik@6020
   537
						"@<title><classname>{$class}</classname></title>@";
tmysik@6020
   538
					if (preg_match ($offsetPattern , $xml, $matchOffset,PREG_OFFSET_CAPTURE)) {
tmysik@6020
   539
						$docPattern = '@<para>(.*?)</para>@s';
tmysik@6020
   540
						if (preg_match ($docPattern, $xml, $match2,null,$matchOffset[0][1])) {
tmysik@6020
   541
							$doc = xml_to_phpdoc($match2[1]);
tmysik@6020
   542
							$classesDoc[$refname]['doc'] = $doc;
tmysik@6020
   543
						}
tmysik@6020
   544
					}
tmysik@6020
   545
				}
tmysik@6020
   546
			}
tmysik@6020
   547
		}
tmysik@6020
   548
	}
tmysik@6020
   549
	return $classesDoc;
tmysik@6020
   550
}
tmysik@6020
   551
tmysik@6020
   552
/**
tmysik@6020
   553
 * Parses PHP documentation
tmysik@6020
   554
 * @param phpdocDir string PHP.net documentation directory
tmysik@6020
   555
 * @return array Constant information gathered from the PHP.net documentation by parsing XML files
tmysik@6020
   556
 */
tmysik@6020
   557
function parse_phpdoc_constants ($phpdocDir) {
tmysik@6020
   558
	exec ("find ".addslashes($phpdocDir)." -name \"*constants.xml\"", $xml_files);
tmysik@6020
   559
	foreach ($xml_files as $xml_file) {
tmysik@6020
   560
		$xml = file_get_contents ($xml_file);
tmysik@6020
   561
tmysik@6020
   562
		if (preg_match ('@xml:id=["\'](.*?)["\']@', $xml, $match)) {
tmysik@6020
   563
			$id = $match[1];
tmysik@6020
   564
			if (preg_match_all ('@<term>\s*<constant>([a-zA-Z_:][a-zA-Z0-9_:]*)</constant>.*?</term>.*?<listitem>(.*?)</listitem>@s', $xml, $match)) {
tmysik@6020
   565
				for ($i = 0; $i < count($match[0]); ++$i) {
tmysik@6020
   566
					$constant = $match[1][$i];
tmysik@6020
   567
					$constantsDoc[$constant]['id'] = $id;
tmysik@6020
   568
					$constantsDoc[$constant]['doc'] = xml_to_phpdoc($match[2][$i]);
tmysik@6020
   569
				}
tmysik@6020
   570
			}
tmysik@6020
   571
			if (preg_match_all (
tmysik@6020
   572
				'@<entry>\s*<constant>([a-zA-Z_][a-zA-Z0-9_]*)</constant>.*?</entry>\s*<entry>\d+</entry>\s*<entry>(.*?)</entry>@s', $xml, $match)
tmysik@6020
   573
				|| preg_match_all ('@<entry>\s*<constant>([a-zA-Z_][a-zA-Z0-9_]*)</constant>.*?</entry>\s*<entry>(.*?)</entry>@s', $xml, $match)) {
tmysik@6020
   574
tmysik@6020
   575
				for ($i = 0; $i < count($match[0]); ++$i) {
tmysik@6020
   576
					$constant = $match[1][$i];
tmysik@6020
   577
					$constantsDoc[$constant]['id'] = $id;
tmysik@6020
   578
					$constantsDoc[$constant]['doc'] = xml_to_phpdoc($match[2][$i]);
tmysik@6020
   579
				}
tmysik@6020
   580
			}
tmysik@6020
   581
		}
tmysik@6020
   582
	}
tmysik@6020
   583
	return $constantsDoc;
tmysik@6020
   584
}
tmysik@6020
   585
tmysik@6020
   586
/**
tmysik@6020
   587
 * Prints ReflectionExtension in format of PHP code
tmysik@6020
   588
 * @param extRef ReflectionExtension object
tmysik@6020
   589
 */
tmysik@6020
   590
function print_extension ($extRef) {
tmysik@6020
   591
    global $functionBlackList;
tmysik@6020
   592
tmysik@6020
   593
	print "\n// Start of {$extRef->getName()} v.{$extRef->getVersion()}\n";
tmysik@6020
   594
tmysik@6020
   595
	// process classes:
tmysik@6020
   596
	$classesRef = $extRef->getClasses();
tmysik@6020
   597
	if (count ($classesRef) > 0) {
tmysik@6020
   598
		foreach ($classesRef as $classRef) {
tmysik@6020
   599
			print_class ($classRef);
tmysik@6020
   600
		}
tmysik@6020
   601
	}
tmysik@6020
   602
tmysik@6020
   603
	// process functions
tmysik@6020
   604
	$funcsRef = $extRef->getFunctions();
tmysik@6020
   605
	if (count ($funcsRef) > 0) {
tmysik@6020
   606
		foreach ($funcsRef as $funcName => $funcRef) {
tmysik@6020
   607
                    if (array_key_exists($funcName, $functionBlackList)) {
tmysik@6020
   608
                        continue;
tmysik@6020
   609
                    }
tmysik@6020
   610
			print_function ($funcRef);
tmysik@6020
   611
		}
tmysik@6020
   612
		print "\n";
tmysik@6020
   613
	}
tmysik@6020
   614
tmysik@6020
   615
	// process constants
tmysik@6020
   616
	$constsRef = $extRef->getConstants();
tmysik@6020
   617
	if (count ($constsRef) > 0) {
tmysik@6020
   618
		print_constants ($constsRef);
tmysik@6020
   619
		print "\n";
tmysik@6020
   620
	}
tmysik@6020
   621
tmysik@6020
   622
	print "// End of {$extRef->getName()} v.{$extRef->getVersion()}\n";
tmysik@6020
   623
}
tmysik@6020
   624
tmysik@6020
   625
/**
tmysik@6020
   626
 * Prints ReflectionClass in format of PHP code
tmysik@6020
   627
 * @param classRef ReflectionClass object
tmysik@6020
   628
 * @param tabs integer[optional] number of tabs for indentation
tmysik@6020
   629
 */
tmysik@6020
   630
function print_class (ReflectionClass $classRef, $tabs = 0) {
tmysik@6391
   631
	global $processedClasses, $preferHtmlProperties, $methodBlackList;
tmysik@6020
   632
	$processedClasses [strtolower($classRef->getName())] = true;
tmysik@6020
   633
tmysik@6020
   634
	print "\n";
tmysik@6020
   635
	print_doccomment ($classRef, $tabs);
tmysik@6020
   636
	print_tabs ($tabs);
tmysik@6020
   637
	if ($classRef->isFinal()) print "final ";
tmysik@6020
   638
tmysik@6020
   639
        if ($classRef->isInterface()) {
tmysik@6020
   640
            print "interface ";
tmysik@6020
   641
        } elseif ($classRef->isTrait()) {
tmysik@6020
   642
            print "trait ";
tmysik@6020
   643
        } else {
tmysik@6389
   644
            if ($classRef->isAbstract()) {
tmysik@6389
   645
                print "abstract ";
tmysik@6389
   646
            }
tmysik@6020
   647
            print "class ";
tmysik@6020
   648
        }
tmysik@6020
   649
	print clean_php_identifier($classRef->getName())." ";
tmysik@6020
   650
tmysik@6020
   651
	// print out parent class
tmysik@6020
   652
	$parentClassRef = $classRef->getParentClass();
tmysik@6020
   653
	if ($parentClassRef) {
tmysik@6020
   654
		print "extends {$parentClassRef->getName()} ";
tmysik@6020
   655
	}
tmysik@6020
   656
tmysik@6020
   657
	// print out interfaces
tmysik@6020
   658
	$interfacesRef = $classRef->getInterfaces();
tmysik@6020
   659
	if (count ($interfacesRef) > 0) {
tmysik@6020
   660
		print $classRef->isInterface() ? "extends " : "implements ";
tmysik@6020
   661
		$i = 0;
tmysik@6020
   662
		foreach ($interfacesRef as $interfaceRef) {
tmysik@6020
   663
			if ($i++ > 0) {
tmysik@6020
   664
				print ", ";
tmysik@6020
   665
			}
tmysik@6020
   666
			print "{$interfaceRef->getName()}";
tmysik@6020
   667
		}
tmysik@6020
   668
	}
tmysik@6020
   669
	print " {\n";
tmysik@6020
   670
tmysik@6020
   671
	// print out traits
tmysik@6020
   672
        $traits = $classRef->getTraits();
tmysik@6020
   673
        if (count($traits)) {
tmysik@6020
   674
            foreach ($traits as $trait => $traitInfo) {
tmysik@6020
   675
                print_tabs($tabs + 1);
tmysik@6020
   676
                print 'use ' . $trait . ';';
tmysik@6020
   677
		print "\n";
tmysik@6020
   678
            }
tmysik@6020
   679
            print "\n";
tmysik@6020
   680
        }
tmysik@6020
   681
tmysik@6020
   682
	// process constants
tmysik@6020
   683
	$constsRef = $classRef->getConstants();
tmysik@6020
   684
	if (count ($constsRef) > 0) {
tmysik@6020
   685
		print_class_constants ($classRef, $constsRef, $tabs + 1);
tmysik@6020
   686
		print "\n";
tmysik@6020
   687
	}
tmysik@6020
   688
tmysik@6020
   689
	// process properties
tmysik@6020
   690
	$propertiesRef = $classRef->getProperties();
tmysik@6100
   691
	if (!in_array(strtolower($classRef->getName()), $preferHtmlProperties)
tmysik@6100
   692
                && count ($propertiesRef) > 0) {
tmysik@6020
   693
		foreach ($propertiesRef as $propertyRef) {
tmysik@6020
   694
			print_property ($propertyRef, $tabs + 1);
tmysik@6020
   695
		}
tmysik@6020
   696
		print "\n";
tmysik@6060
   697
	} else {
tmysik@6060
   698
        // #188245 - try to find them directly in HTML
tmysik@6060
   699
        $properties = parse_properties_from_html_file('class.' . strtolower($classRef->getName()) . '.html', $classRef->getName());
tmysik@6060
   700
        if (count($properties)) {
tmysik@6060
   701
            foreach ($properties as $property) {
tmysik@6060
   702
                print_field($property, $tabs + 1);
tmysik@6060
   703
            }
tmysik@6060
   704
            print "\n";
tmysik@6060
   705
        }
tmysik@6060
   706
    }
tmysik@6020
   707
tmysik@6020
   708
	// process methods
tmysik@6020
   709
	/* @var $classRef ReflectionClass */
tmysik@6020
   710
	$methodsRef = $classRef->getMethods();
tmysik@6020
   711
	if (count ($methodsRef) > 0) {
tmysik@6020
   712
		foreach ($methodsRef as $methodRef) {
tmysik@6391
   713
            /* @var $methodRef ReflectionMethod */
tmysik@6391
   714
            if (in_array(strtolower($methodRef->getName()), $methodBlackList)) {
tmysik@6391
   715
                continue;
tmysik@6391
   716
            }
tmysik@6020
   717
			print_method($classRef, $methodRef, $tabs + 1);
tmysik@6020
   718
		}
tmysik@6020
   719
		print "\n";
tmysik@6020
   720
	}
tmysik@6020
   721
	print_tabs ($tabs);
tmysik@6020
   722
	print "}\n";
tmysik@6020
   723
}
tmysik@6020
   724
tmysik@6020
   725
/**
tmysik@6020
   726
 * Prints ReflectionProperty in format of PHP code
tmysik@6020
   727
 * @param ReflectionProperty $propertyRef  object
tmysik@6020
   728
 * @param integer[optional] tabs  number of tabs for indentation
tmysik@6020
   729
 */
tmysik@6020
   730
function print_property ($propertyRef, $tabs = 0) {
tmysik@6020
   731
	print_doccomment ($propertyRef, $tabs);
tmysik@6020
   732
	print_tabs ($tabs);
tmysik@6020
   733
	print_modifiers ($propertyRef, true);
tmysik@6057
   734
        $name = $propertyRef->getName();
tmysik@6057
   735
        if (substr($name, 0, 1) !== '$') {
tmysik@6057
   736
            $name = '$' . $name;
tmysik@6057
   737
        }
tmysik@6057
   738
        print $name . ";\n";
tmysik@6020
   739
}
tmysik@6020
   740
tmysik@6060
   741
/**
tmysik@6060
   742
 * Prints Field in format of PHP code
tmysik@6060
   743
 * @param NetBeans_Field $field  object
tmysik@6060
   744
 * @param integer[optional] tabs  number of tabs for indentation
tmysik@6060
   745
 */
tmysik@6060
   746
function print_field (NetBeans_Field $field, $tabs = 0) {
tmysik@6060
   747
    // documentation
tmysik@6060
   748
    $fieldType = $field->getType();
tmysik@6060
   749
    $fieldDoc = $field->getDocumentation();
tmysik@6060
   750
    $fieldDoc = trim(strip_tags($fieldDoc, '<p>,<strong>,<code>,<a>'));
tmysik@6060
   751
    // replace hyperlinks
tmysik@6060
   752
    $fieldDoc = preg_replace('%<(a|strong)[^>]*>%', '<b>', $fieldDoc);
tmysik@6060
   753
    $fieldDoc = preg_replace('%<p[^>]+>%', '<p>', $fieldDoc);
tmysik@6060
   754
    $fieldDoc = str_replace('</a>', '</b>', $fieldDoc);
tmysik@6060
   755
    $fieldDoc = str_replace('</strong>', '</b>', $fieldDoc);
tmysik@6060
   756
    $fieldDoc = preg_replace('%^<p>(.+)</p>$%s', '<p style="margin-top:0;">\\1</p>', $fieldDoc);
tmysik@6060
   757
tmysik@6060
   758
    print_tabs ($tabs);
tmysik@6060
   759
    print "/**\n";
tmysik@6060
   760
    foreach (preg_split('%\n|\r%', $fieldDoc) as $line) {
tmysik@6060
   761
        $line = trim($line);
tmysik@6060
   762
        if (!$line) {
tmysik@6060
   763
            continue;
tmysik@6060
   764
        }
tmysik@6060
   765
        print_tabs($tabs);
tmysik@6060
   766
        print " * $line\n";
tmysik@6060
   767
    }
tmysik@6060
   768
    print_tabs($tabs);
tmysik@6060
   769
    print " * @var $fieldType\n";
tmysik@6060
   770
    print_tabs($tabs);
tmysik@6060
   771
    print " */\n";
tmysik@6060
   772
    // tabs
tmysik@6060
   773
	print_tabs($tabs);
tmysik@6060
   774
    // modifiers
tmysik@6060
   775
    $print = implode(' ', $field->getModifiers());
tmysik@6060
   776
    $print = str_replace("final", "", $print);
tmysik@6060
   777
    $print = str_replace("abstract", "", $print);
tmysik@6060
   778
    $print = str_replace("readonly", "", $print);
tmysik@6100
   779
    $print = trim($print);
tmysik@6100
   780
    if (!$print) {
tmysik@6100
   781
        // no modifiers
tmysik@6100
   782
        $print = 'public';
tmysik@6100
   783
    }
tmysik@6100
   784
    print $print;
tmysik@6060
   785
    print " ";
tmysik@6060
   786
    $name = $field->getName();
tmysik@6060
   787
    if (substr($name, 0, 1) !== '$') {
tmysik@6060
   788
        $name = '$' . $name;
tmysik@6060
   789
    }
tmysik@6060
   790
    print $name . ";\n";
tmysik@6060
   791
}
tmysik@6060
   792
tmysik@6020
   793
function print_function ($functionRef, $tabs = 0) {
tmysik@6020
   794
    print_method(null, $functionRef, $tabs);
tmysik@6020
   795
}
tmysik@6020
   796
tmysik@6020
   797
function print_method ($classRef, $functionRef, $tabs = 0) {
tmysik@6020
   798
	global $functionsDoc;
tmysik@6020
   799
	global $processedFunctions;
tmysik@6020
   800
tmysik@6020
   801
	$funckey = make_funckey_from_ref ($functionRef);
tmysik@6020
   802
	$processedFunctions[$funckey] = true;
tmysik@6020
   803
tmysik@6020
   804
	print "\n";
tmysik@6020
   805
        $modifiers = null;
tmysik@6020
   806
	print_doccomment ($functionRef, $tabs);
tmysik@6020
   807
	print_tabs ($tabs);
tmysik@6020
   808
	if (!($functionRef instanceof ReflectionFunction)) {
tmysik@6020
   809
		print_modifiers ($functionRef);
tmysik@6020
   810
                $modifiers = Reflection::getModifierNames($functionRef->getModifiers());
tmysik@6020
   811
	}
tmysik@6020
   812
tmysik@6020
   813
	print "function ";
tmysik@6020
   814
	if ($functionRef->returnsReference()) {
tmysik@6020
   815
		print "&";
tmysik@6020
   816
	}
tmysik@6325
   817
	$functionName = $functionRef->getName();
tmysik@6325
   818
	print "$functionName(";
tmysik@6020
   819
	$parameters = @$functionsDoc[$funckey]['parameters'];
tmysik@6020
   820
	if ($parameters) {
tmysik@6020
   821
		print_parameters ($parameters);
tmysik@6020
   822
	} else {
tmysik@6020
   823
		print_parameters_ref ($functionRef->getParameters());
tmysik@6020
   824
	}
tmysik@6020
   825
	print ")";
tmysik@6325
   826
        $returntype = sanitizeType(@$functionsDoc[$funckey]['returntype']);
tmysik@6325
   827
        if ($returntype
tmysik@6325
   828
                && $functionName !== '__construct') {
tmysik@6325
   829
            print ': ' . $returntype;
tmysik@6325
   830
        }
tmysik@6020
   831
        $body = true;
tmysik@6020
   832
        if ($classRef != null && $classRef->isInterface()) {
tmysik@6020
   833
            $body = false;
tmysik@6020
   834
        } elseif (is_array($modifiers)) {
tmysik@6020
   835
            foreach ($modifiers as $modifier) {
tmysik@6020
   836
                if ($modifier == "abstract") {
tmysik@6020
   837
                    $body = false;
tmysik@6020
   838
                    break;
tmysik@6020
   839
                }
tmysik@6020
   840
            }
tmysik@6020
   841
        }
tmysik@6020
   842
        if ($body) {
tmysik@6020
   843
            print " {}";
tmysik@6020
   844
        } else {
tmysik@6020
   845
            print ";";
tmysik@6020
   846
        }
tmysik@6020
   847
	print "\n";
tmysik@6020
   848
}
tmysik@6020
   849
tmysik@6020
   850
tmysik@6020
   851
/**
tmysik@6020
   852
 * Prints ReflectionParameter in format of PHP code
tmysik@6020
   853
 * @param parameters array information from PHP.net documentation
tmysik@6020
   854
 */
tmysik@6020
   855
function print_parameters ($parameters) {
tmysik@6020
   856
	$i = 0;
tmysik@6020
   857
	foreach ($parameters as $parameter) {
tmysik@6020
   858
		if ($parameter['name'] != "...") {
tmysik@6386
   859
			if ($i++ > 0) {
tmysik@6386
   860
				print ", ";
tmysik@6386
   861
			}
tmysik@6385
   862
                        $type = sanitizeType($parameter['type']);
tmysik@6386
   863
			if ($type) {
tmysik@6386
   864
				print "{$type} ";
tmysik@6386
   865
			}
tmysik@6386
   866
			if (@$parameter['isreference']) {
tmysik@6386
   867
				print "&";
tmysik@6386
   868
			}
tmysik@6386
   869
                        print "\${$parameter['name']}";
tmysik@6020
   870
			if (@$parameter['isoptional']) {
tmysik@6202
   871
				if (array_key_exists('defaultvalue', $parameter)) {
tmysik@6020
   872
					$value = $parameter['defaultvalue'];
tmysik@6325
   873
                                        if ((is_numeric ($value) && $type != 'string')
tmysik@6325
   874
                                                || in_array(strtolower($value), array('true', 'false', 'null', 'array()'))
tmysik@6020
   875
                                                || (substr($value, 0, 1) == '\'' && substr($value, -1) == '\'')
tmysik@6325
   876
                                                || (substr($value, 0, 1) == '"' && substr($value, -1) == '"')
tmysik@6325
   877
                                                || (substr($value, 0, 2) == '__' && substr($value, -2) == '__')
tmysik@6325
   878
                                                || isConstant($value)) {
tmysik@6020
   879
                                            // no apostrophes
tmysik@6020
   880
                                        } else {
tmysik@6020
   881
                                            $value = "'{$value}'";
tmysik@6020
   882
                                        }
tmysik@6386
   883
                                        print " = {$value}";
tmysik@6020
   884
				} else {
tmysik@6386
   885
                                        print " = null";
tmysik@6020
   886
				}
tmysik@6020
   887
			}
tmysik@6385
   888
tmysik@6020
   889
		}
tmysik@6020
   890
	}
tmysik@6020
   891
}
tmysik@6020
   892
tmysik@6020
   893
/**
tmysik@6020
   894
 * Prints ReflectionParameter in format of PHP code
tmysik@6020
   895
 * @param paramsRef ReflectionParameter[] array of objects
tmysik@6020
   896
 */
tmysik@6020
   897
function print_parameters_ref ($paramsRef) {
tmysik@6020
   898
	$i = 0;
tmysik@6020
   899
	foreach ($paramsRef as $paramRef) {
tmysik@6385
   900
            /* @var $paramRef ReflectionParameter */
tmysik@6385
   901
            if ($paramRef->allowsNull()) {
tmysik@6385
   902
                echo '?';
tmysik@6385
   903
            }
tmysik@6020
   904
		if ($paramRef->isArray()) {
tmysik@6020
   905
			print "array ";
tmysik@6020
   906
		} else {
tmysik@6020
   907
			if ($className = get_parameter_classname($paramRef)) {
tmysik@6020
   908
				print "{$className} ";
tmysik@6020
   909
			}
tmysik@6020
   910
		}
tmysik@6020
   911
		$name = $paramRef->getName() ? $paramRef->getName() : "var".($i+1);
tmysik@6020
   912
		if ($name != "...") {
tmysik@6020
   913
			if ($i++ > 0) {
tmysik@6020
   914
				print ", ";
tmysik@6020
   915
			}
tmysik@6020
   916
			if ($paramRef->isPassedByReference()) {
tmysik@6020
   917
				print "&";
tmysik@6020
   918
			}
tmysik@6020
   919
			print "\${$name}";
tmysik@6020
   920
			if ($paramRef->allowsNull()) {
tmysik@6020
   921
				print " = null";
tmysik@6020
   922
			} else if ($paramRef->isDefaultValueAvailable()) {
tmysik@6020
   923
				$value = $paramRef->getDefaultValue();
tmysik@6020
   924
				if (!is_numeric ($value)) {
tmysik@6020
   925
					$value = "'{$value}'";
tmysik@6020
   926
				}
tmysik@6020
   927
				print " = {$value}";
tmysik@6020
   928
			}
tmysik@6020
   929
		}
tmysik@6020
   930
	}
tmysik@6020
   931
}
tmysik@6020
   932
tmysik@6020
   933
/**
tmysik@6020
   934
 * Prints constants in format of PHP code
tmysik@6020
   935
 * @param constants array containing constants, where key is a name of constant
tmysik@6020
   936
 * @param tabs integer[optional] number of tabs for indentation
tmysik@6020
   937
 */
tmysik@6020
   938
function print_constants ($constants, $tabs = 0) {
tmysik@6020
   939
	foreach ($constants as $name => $value) {
tmysik@6020
   940
		print_constant ($name, $value, $tabs);
tmysik@6020
   941
	}
tmysik@6020
   942
}
tmysik@6020
   943
tmysik@6020
   944
function print_constant ($name, $value = null, $tabs = 0) {
tmysik@6020
   945
	global $constantsDoc;
tmysik@6020
   946
	global $processedConstants;
tmysik@6020
   947
	$processedConstants [$name] = true;
tmysik@6020
   948
tmysik@6020
   949
	if ($value === null) {
tmysik@6020
   950
		$value = @constant ($name);
tmysik@6020
   951
	}
tmysik@6020
   952
	$value = escape_const_value ($value);
tmysik@6020
   953
tmysik@6020
   954
	$doc = @$constantsDoc[$name]['doc'];
tmysik@6020
   955
	if ($doc) {
tmysik@6020
   956
		print "\n";
tmysik@6020
   957
		print_tabs ($tabs);
tmysik@6020
   958
		print "/**\n";
tmysik@6020
   959
		print_tabs ($tabs);
tmysik@6020
   960
		print " * ".newline_to_phpdoc($doc, $tabs)."\n";
tmysik@6020
   961
		print_tabs ($tabs);
tmysik@6020
   962
		print " * @link ".make_url($constantsDoc[$name]['id'])."\n";
tmysik@6020
   963
		print_tabs ($tabs);
tmysik@6020
   964
		print " */\n";
tmysik@6020
   965
	}
tmysik@6020
   966
	print_tabs ($tabs);
tmysik@6020
   967
	print "define ('{$name}', {$value});\n";
tmysik@6020
   968
}
tmysik@6020
   969
tmysik@6020
   970
function escape_const_value ($value) {
tmysik@6020
   971
	if (is_resource($value)) {
tmysik@6020
   972
		$value = "\"${value}\"";
tmysik@6020
   973
	} else if (!is_numeric ($value) && !is_bool ($value) && $value !== null) {
tmysik@6020
   974
		$value = '"'.addcslashes ($value, "\"\r\n\t").'"';
tmysik@6020
   975
	} else if ($value === null) {
tmysik@6020
   976
		$value = "null";
tmysik@6020
   977
	} else if ($value === false) {
tmysik@6020
   978
		$value = "false";
tmysik@6020
   979
	} else if ($value === true) {
tmysik@6020
   980
		$value = "true";
tmysik@6020
   981
	}
tmysik@6020
   982
	return $value;
tmysik@6020
   983
}
tmysik@6020
   984
tmysik@6020
   985
/**
tmysik@6020
   986
 * Prints class constants in format of PHP code
tmysik@6020
   987
 * @param constants array containing constants, where key is a name of constant
tmysik@6020
   988
 * @param tabs integer[optional] number of tabs for indentation
tmysik@6020
   989
 */
tmysik@6020
   990
function print_class_constants ($classRef, $constants, $tabs = 0) {
tmysik@6020
   991
    global $constantsDoc;
tmysik@6020
   992
    global $processedConstants;
tmysik@6020
   993
tmysik@6020
   994
tmysik@6020
   995
    //$doc = @$constantsDoc[$name]['doc'];
tmysik@6020
   996
    foreach ($constants as $name => $value) {
tmysik@6020
   997
        $value = escape_const_value ($value);
tmysik@6020
   998
        $clsName = $classRef->getName();
tmysik@6020
   999
        $idx = "$clsName::$name";
tmysik@6020
  1000
        $doc = @$constantsDoc[$idx]['doc'];
tmysik@6020
  1001
        if ($doc) {
tmysik@6020
  1002
            print "\n";
tmysik@6020
  1003
            print_tabs ($tabs);
tmysik@6020
  1004
            print "/**\n";
tmysik@6020
  1005
            print_tabs ($tabs);
tmysik@6020
  1006
            print " * ".newline_to_phpdoc($doc, $tabs)."\n";
tmysik@6020
  1007
            print_tabs ($tabs);
tmysik@6020
  1008
            print " * @link ".make_url($constantsDoc[$idx]['id'])."\n";
tmysik@6020
  1009
            print_tabs ($tabs);
tmysik@6020
  1010
            print " */\n";
tmysik@6020
  1011
        }
tmysik@6020
  1012
        print_tabs ($tabs);
tmysik@6020
  1013
        print "const {$name} = {$value};\n";
tmysik@6020
  1014
    }
tmysik@6020
  1015
}
tmysik@6020
  1016
tmysik@6020
  1017
/**
tmysik@6020
  1018
 * Prints modifiers of reflection object in format of PHP code
tmysik@6020
  1019
 * @param ref Reflection some reflection object
tmysik@6020
  1020
 */
tmysik@6020
  1021
function print_modifiers ($ref, $forFields = false) {
tmysik@6020
  1022
	$modifiers = Reflection::getModifierNames ($ref->getModifiers());
tmysik@6020
  1023
	if (count ($modifiers) > 0) {
tmysik@6020
  1024
                $print = implode(' ', $modifiers);
tmysik@6020
  1025
                if ($forFields) {
tmysik@6020
  1026
                    $print = str_replace("final", "", $print);
tmysik@6020
  1027
                    $print = str_replace("abstract", "", $print);
tmysik@6060
  1028
                    $print = str_replace("readonly", "", $print);
tmysik@6020
  1029
                }
tmysik@6020
  1030
		print trim($print);
tmysik@6020
  1031
		print " ";
tmysik@6020
  1032
	}
tmysik@6020
  1033
}
tmysik@6020
  1034
tmysik@6020
  1035
/**
tmysik@6020
  1036
 * Makes PHP Manual URL from the given ID
tmysik@6020
  1037
 * @param id PHP Element ID
tmysik@6020
  1038
 * @return URL
tmysik@6020
  1039
 */
tmysik@6020
  1040
function make_url ($id) {
tmysik@6388
  1041
	global $lang;
tmysik@6388
  1042
	return "http://php.net/manual/{$lang}/{$id}.php";
tmysik@6020
  1043
}
tmysik@6020
  1044
tmysik@6020
  1045
/**
tmysik@6020
  1046
 * Prints PHPDOC comment before specified reflection object
tmysik@6020
  1047
 * @param ref Reflection some reflection object
tmysik@6020
  1048
 * @param tabs integer[optional] number of tabs for indentation
tmysik@6020
  1049
 */
tmysik@6020
  1050
function print_doccomment ($ref, $tabs = 0) {
tmysik@6020
  1051
	global $functionsDoc;
tmysik@6020
  1052
	global $classesDoc;
tmysik@6020
  1053
        global $fieldsDoc;
tmysik@6391
  1054
        global $methodBlackList;
tmysik@6020
  1055
tmysik@6020
  1056
	$docComment = $ref->getDocComment();
tmysik@6020
  1057
	if ($docComment) {
tmysik@6020
  1058
		print_tabs ($tabs);
tmysik@6020
  1059
		print "{$docComment}\n";
tmysik@6020
  1060
	}
tmysik@6020
  1061
	else if ($ref instanceof ReflectionClass) {
tmysik@6020
  1062
		$refname = strtolower($ref->getName());
tmysik@6020
  1063
		if (@$classesDoc[$refname]) {
tmysik@6020
  1064
			print_tabs ($tabs);
tmysik@6020
  1065
			print "/**\n";
tmysik@6020
  1066
			$doc = @$classesDoc[$refname]['doc'];
tmysik@6020
  1067
			if ($doc) {
tmysik@6020
  1068
				$doc = newline_to_phpdoc ($doc, $tabs);
tmysik@6020
  1069
				print_tabs ($tabs);
tmysik@6020
  1070
				print " * {$doc}\n";
tmysik@6020
  1071
			}
tmysik@6111
  1072
                        // @method
tmysik@6111
  1073
                        foreach ($ref->getMethods() as $method) {
tmysik@6391
  1074
                            if (in_array(strtolower($method->getName()), $methodBlackList)) {
tmysik@6391
  1075
                                print_magic_method($ref, $method, $tabs);
tmysik@6391
  1076
                            }
tmysik@6111
  1077
                        }
tmysik@6020
  1078
			if (@$classesDoc[$refname]['id']) {
tmysik@6020
  1079
				print_Tabs ($tabs);
tmysik@6020
  1080
				$url = make_url ($classesDoc[$refname]['id']);
tmysik@6020
  1081
				print " * @link {$url}\n";
tmysik@6020
  1082
			}
tmysik@6020
  1083
			print_tabs ($tabs);
tmysik@6020
  1084
			print " */\n";
tmysik@6020
  1085
		}
tmysik@6020
  1086
	}
tmysik@6020
  1087
	else if ($ref instanceof ReflectionFunctionAbstract) {
tmysik@6020
  1088
		$funckey = make_funckey_from_ref ($ref);
tmysik@6020
  1089
                $id = @$functionsDoc[$funckey]['id'];
tmysik@6020
  1090
                $ver_info = findVerInfo($id);
tmysik@6020
  1091
                $desc = @$functionsDoc[$funckey]['quickref'];
tmysik@6020
  1092
		$returntype = "";
tmysik@6020
  1093
                $returndoc = "";
tmysik@6020
  1094
                if (strpos($funckey, "::__construct") === false) {
tmysik@6020
  1095
                    $returntype = @$functionsDoc[$funckey]['returntype'];
tmysik@6020
  1096
                    $returndoc = newline_to_phpdoc (@$functionsDoc[$funckey]['returndoc'], $tabs);
tmysik@6020
  1097
                }
tmysik@6020
  1098
tmysik@6020
  1099
		$paramsRef = $ref->getParameters();
tmysik@6020
  1100
		$parameters = @$functionsDoc[$funckey]['parameters'];
tmysik@6020
  1101
tmysik@6020
  1102
		if ($desc || count ($paramsRef) > 0 || $parameters || $returntype) {
tmysik@6020
  1103
			print_tabs ($tabs);
tmysik@6020
  1104
			print "/**\n";
tmysik@6020
  1105
                        if($ver_info) {
tmysik@6020
  1106
                            print_tabs ($tabs);
tmysik@6020
  1107
                            print " * {$ver_info}<br/>\n";
tmysik@6020
  1108
                        }
tmysik@6020
  1109
                        if ($desc) {
tmysik@6020
  1110
				print_tabs ($tabs);
tmysik@6020
  1111
				print " * {$desc}\n";
tmysik@6020
  1112
			}
tmysik@6020
  1113
			if (@$functionsDoc[$funckey]['id']) {
tmysik@6020
  1114
				print_tabs ($tabs);
tmysik@6020
  1115
				$url = make_url ($functionsDoc[$funckey]['id']);
tmysik@6020
  1116
				print " * @link {$url}\n";
tmysik@6020
  1117
			}
tmysik@6020
  1118
                        if (!@$functionsDoc[$funckey]['deprecated']) {
tmysik@6020
  1119
                            if($parameters) {
tmysik@6020
  1120
                                foreach ($parameters as $parameter) {
tmysik@6020
  1121
                                    print_tabs($tabs);
tmysik@6020
  1122
                                    print " * @param {$parameter['type']} \${$parameter['name']}";
tmysik@6020
  1123
                                    if (@$parameter['isoptional']) {
tmysik@6020
  1124
                                        print " [optional]";
tmysik@6020
  1125
                                    }
tmysik@6020
  1126
                                    $paramdoc = @$parameter['paramdoc'];
tmysik@6020
  1127
                                    if ($paramdoc && $paramdoc != "<p>\n</p>") {
tmysik@6020
  1128
                                        $paramdoc = newline_to_phpdoc(@$parameter['paramdoc'], $tabs);
tmysik@6020
  1129
                                        print " {$paramdoc}";
tmysik@6020
  1130
                                    }
tmysik@6020
  1131
                                    print "\n";
tmysik@6020
  1132
                                }
tmysik@6020
  1133
                            } else {
tmysik@6020
  1134
                                $i = 0;
tmysik@6020
  1135
                                foreach ($paramsRef as $paramRef) {
tmysik@6020
  1136
                                    print_tabs($tabs);
tmysik@6020
  1137
                                    $name = $paramRef->getName() ? $paramRef->getName() : "var".++$i;
tmysik@6020
  1138
                                    print " * @param";
tmysik@6020
  1139
                                    if($className = get_parameter_classname($paramRef)) {
tmysik@6020
  1140
                                        print " {$className}";
tmysik@6020
  1141
                                        if($paramRef->isArray()) {
tmysik@6020
  1142
                                            print "[]";
tmysik@6020
  1143
                                        }
tmysik@6020
  1144
                                    }
tmysik@6020
  1145
                                    print " \${$name}";
tmysik@6020
  1146
                                    if($paramRef->isOptional()) {
tmysik@6020
  1147
                                        print " [optional]";
tmysik@6020
  1148
                                    }
tmysik@6020
  1149
                                    print "\n";
tmysik@6020
  1150
                                }
tmysik@6020
  1151
                            }
tmysik@6020
  1152
                            if ($returntype || $returndoc) {
tmysik@6020
  1153
                                if (!$returntype) {
tmysik@6020
  1154
                                    $returntype = 'mixed';
tmysik@6020
  1155
                                }
tmysik@6020
  1156
                                    print_tabs ($tabs);
tmysik@6020
  1157
                                    print " * @return " . trim("{$returntype} {$returndoc}") . "\n";
tmysik@6020
  1158
                            }
tmysik@6020
  1159
                        }
tmysik@6020
  1160
			print_tabs ($tabs);
tmysik@6020
  1161
			print " */\n";
tmysik@6020
  1162
		}
tmysik@6020
  1163
	}else if ($ref instanceof ReflectionProperty) {
tmysik@6020
  1164
            $property_from_ref = make_property_from_ref($ref);
tmysik@6020
  1165
            $fieldName = @$fieldsDoc[$property_from_ref]['field'];
tmysik@6020
  1166
            $fieldType = @$fieldsDoc[$property_from_ref]['type'];
tmysik@6020
  1167
            if (isset ($fieldName) && isset ($fieldType)) {
tmysik@6020
  1168
                print_tabs ($tabs);
tmysik@6020
  1169
                print "/**\n";
tmysik@6020
  1170
                print_tabs ($tabs);
tmysik@6020
  1171
                print " * @var $fieldType\n";
tmysik@6020
  1172
                print_tabs ($tabs);
tmysik@6020
  1173
                print " */\n";
tmysik@6020
  1174
            }
tmysik@6020
  1175
        }
tmysik@6020
  1176
}
tmysik@6020
  1177
tmysik@6111
  1178
function print_magic_method(ReflectionClass $classRef, ReflectionMethod $methodRef, $tabs = 0) {
tmysik@6111
  1179
    global $functionsDoc;
tmysik@6111
  1180
    global $processedFunctions;
tmysik@6111
  1181
tmysik@6111
  1182
    $funckey = make_funckey_from_ref($methodRef);
tmysik@6111
  1183
    $processedFunctions[$funckey] = true;
tmysik@6111
  1184
tmysik@6111
  1185
    print_tabs($tabs);
tmysik@6111
  1186
    print " * @method ";
tmysik@6111
  1187
    $returntype = @$functionsDoc[$funckey]['returntype'];
tmysik@6111
  1188
    $returndoc = @$functionsDoc[$funckey]['returndoc'];
tmysik@6111
  1189
    if ($returntype
tmysik@6111
  1190
            || $returndoc) {
tmysik@6111
  1191
        if (!$returntype) {
tmysik@6111
  1192
            $returntype = 'mixed';
tmysik@6111
  1193
        }
tmysik@6111
  1194
        print $returntype . " ";
tmysik@6111
  1195
    }
tmysik@6111
  1196
    print $methodRef->getName() . "(";
tmysik@6111
  1197
    $parameters = @$functionsDoc[$funckey]['parameters'];
tmysik@6111
  1198
    if ($parameters) {
tmysik@6111
  1199
        print_parameters($parameters);
tmysik@6111
  1200
    } else {
tmysik@6111
  1201
        print_parameters_ref($methodRef->getParameters());
tmysik@6111
  1202
    }
tmysik@6111
  1203
    print ")";
tmysik@6111
  1204
    $id = @$functionsDoc[$funckey]['id'];
tmysik@6111
  1205
    $ver_info = findVerInfo($id);
tmysik@6111
  1206
    $docComment = @$functionsDoc[$funckey]['quickref'];
tmysik@6111
  1207
    if ($ver_info
tmysik@6111
  1208
            || $docComment) {
tmysik@6111
  1209
        print " ";
tmysik@6111
  1210
        if ($ver_info) {
tmysik@6111
  1211
            print $ver_info;
tmysik@6111
  1212
        }
tmysik@6111
  1213
        if ($docComment) {
tmysik@6111
  1214
            if ($ver_info) {
tmysik@6111
  1215
                print "<br/>";
tmysik@6111
  1216
            }
tmysik@6111
  1217
            print $docComment;
tmysik@6111
  1218
        }
tmysik@6111
  1219
    }
tmysik@6111
  1220
    print "\n";
tmysik@6111
  1221
}
tmysik@6111
  1222
tmysik@6020
  1223
/**
tmysik@6020
  1224
 * Converts XML entities to human readable string for PHPDOC
tmysik@6020
  1225
 * @param str string
tmysik@6020
  1226
 * @return string
tmysik@6020
  1227
 */
tmysik@6020
  1228
function xml_to_phpdoc ($str) {
tmysik@6020
  1229
    $str = str_replace ("&php.ini;", "###(i)###php.ini###(/i)###", $str); // XXX will be replaced in strip_tags_special()
tmysik@6020
  1230
    $str = replace_entities($str);
tmysik@6020
  1231
        $str = strip_tags_special ($str);
tmysik@6020
  1232
	$str = preg_replace ("/  */", " ", $str);
tmysik@6020
  1233
	$str = str_replace ("*/", "* /", $str);
tmysik@6112
  1234
	$str = str_replace ("“", "&quot;", $str);
tmysik@6112
  1235
	$str = str_replace ("”", "&quot;", $str);
tmysik@6020
  1236
	$str = preg_replace ("/[\r\n][\t ]/", "\n", $str);
tmysik@6020
  1237
        $str = trim($str);
tmysik@6020
  1238
	return $str;
tmysik@6020
  1239
}
tmysik@6020
  1240
tmysik@6020
  1241
/**
tmysik@6020
  1242
 * Converts newlines to PHPDOC prefixes in the given string
tmysik@6020
  1243
 * @param str string
tmysik@6020
  1244
 * @param tabs integer[optional] number of tabs for indentation
tmysik@6020
  1245
 * @return string PHPDOC string
tmysik@6020
  1246
 */
tmysik@6020
  1247
function newline_to_phpdoc ($str, $tabs = 0) {
tmysik@6020
  1248
	$str = preg_replace ("@\s*[\r\n]+@", "\n".str_repeat("\t", $tabs)." * ", $str);
tmysik@6020
  1249
	return $str;
tmysik@6020
  1250
}
tmysik@6020
  1251
tmysik@6020
  1252
/**
tmysik@6020
  1253
 * Prints specified number of tabs
tmysik@6020
  1254
 * @param tabs integer number of tabs to print
tmysik@6020
  1255
 */
tmysik@6020
  1256
function print_tabs ($tabs) {
tmysik@6020
  1257
	print str_repeat("\t", $tabs);
tmysik@6020
  1258
}
tmysik@6020
  1259
tmysik@6020
  1260
/**
tmysik@6020
  1261
 * Returns class name from given parameter reference, this method is a workaround
tmysik@6020
  1262
 * for the case when exception is thrown from getClass() when such classname does not exist.
tmysik@6020
  1263
 */
tmysik@6020
  1264
function get_parameter_classname(ReflectionParameter $paramRef) {
tmysik@6020
  1265
	try {
tmysik@6020
  1266
		if ($classRef = $paramRef->getClass()) {
tmysik@6020
  1267
			return $classRef->getName();
tmysik@6020
  1268
		}
tmysik@6020
  1269
	} catch (Exception $e) {
tmysik@6020
  1270
		if (preg_match('/Class (\w+) does not exist/', $e->getMessage(), $matches)) {
tmysik@6020
  1271
			return $matches[1];
tmysik@6020
  1272
		}
tmysik@6020
  1273
	}
tmysik@6020
  1274
	return null;
tmysik@6020
  1275
}
tmysik@6020
  1276
tmysik@6020
  1277
/**
tmysik@6020
  1278
 * Starts outputing to the new file
tmysik@6020
  1279
 */
tmysik@6020
  1280
function begin_file_output() {
tmysik@6020
  1281
	ob_start();
tmysik@6020
  1282
	print "<?php\n";
tmysik@6020
  1283
}
tmysik@6020
  1284
tmysik@6020
  1285
/**
tmysik@6020
  1286
 * Ends outputing, and dumps the output to the specified file
tmysik@6020
  1287
 * @param filename File to dump the output
tmysik@6020
  1288
 */
tmysik@6020
  1289
function finish_file_output($filename) {
tmysik@6020
  1290
	//if (file_exists ($filename)) {
tmysik@6020
  1291
	//	rename ($filename, "{$filename}.bak");
tmysik@6020
  1292
	//}
tmysik@6020
  1293
	print "?>\n";
tmysik@6111
  1294
	file_put_contents (str_replace(" ", "-", $filename), ob_get_contents());
tmysik@6020
  1295
	ob_end_clean();
tmysik@6020
  1296
}
tmysik@6020
  1297
tmysik@6020
  1298
/**
tmysik@6020
  1299
 * Strips xml tags from the string like the standard strip_tags() function
tmysik@6020
  1300
 * would do, but also translates some of the docbook tags (such as tables
tmysik@6020
  1301
 * an paragraphs) to proper html tags
tmysik@6020
  1302
 * @param str string
tmysik@6020
  1303
 * @return string
tmysik@6020
  1304
 */
tmysik@6020
  1305
function strip_tags_special ($str) {
tmysik@6020
  1306
    // methodsynopsis
tmysik@6020
  1307
//    $str = method_to_phpdoc($str);
tmysik@6020
  1308
    // first mask and translate the tags to preseve
tmysik@6020
  1309
    $str = preg_replace ("/<(\/?)table>/", "###($1table)###", $str);
tmysik@6020
  1310
    $str = str_replace ("<row>", "###(tr valign=\"top\")###", $str);
tmysik@6020
  1311
    $str = str_replace ("</row>", "###(/tr)###", $str);
tmysik@6020
  1312
    $str = preg_replace ("/<(\/?)entry>/", "###($1td)###", $str);
tmysik@6020
  1313
    $str = preg_replace ("/<(\/?)para>/", "###($1p)###", $str);
tmysik@6020
  1314
    $str = preg_replace ("/<(\/?)p>/", "###($1p)###", $str);
tmysik@6020
  1315
    // remove cdata
tmysik@6020
  1316
    $str = str_replace ("<![CDATA[", "###(pre)###", $str);
tmysik@6020
  1317
    $str = str_replace ("]]>", "###(/pre)###", $str);
tmysik@6020
  1318
    // preserve php samples; XXX sample for preg_match_all
tmysik@6020
  1319
    $str = str_replace ("<?php", "###(code)###", $str);
tmysik@6020
  1320
    $str = str_replace ("?>", "###(/code)###", $str);
tmysik@6020
  1321
    // handle "<pre><code>"
tmysik@6020
  1322
    $str = preg_replace ("/###\(pre\)###\s*\n\s*###\(code\)###/", "###(code)###", $str);
tmysik@6020
  1323
    $str = preg_replace ("/###\(\/code\)###\s*\n\s*###\(\/pre\)###/", "###(/code)###", $str);
tmysik@6020
  1324
    // constant & function etc.
tmysik@6020
  1325
    $str = preg_replace ("%<(/)?(constant|function|classname|methodname|methodparam)[^>]*>%", "###(\\1b)###", $str);
tmysik@6020
  1326
    $str = preg_replace ("%<(/)?(parameter)[^>]*>%", "###(\\1i)###", $str);
tmysik@6020
  1327
    // now strip the remaining tags
tmysik@6020
  1328
    $str = strip_tags ($str);
tmysik@6020
  1329
    // and restore the translated ones
tmysik@6020
  1330
    $str = str_replace ("###(", "<", $str);
tmysik@6020
  1331
    $str = str_replace (")###", ">", $str);
tmysik@6020
  1332
    return $str;
tmysik@6020
  1333
}
tmysik@6020
  1334
tmysik@6020
  1335
// XXX, see set_error_handler
tmysik@6020
  1336
function method_to_phpdoc($str) {
tmysik@6020
  1337
    $tmp = array();
tmysik@6020
  1338
    $methodsynopsis = preg_match_all ('@<methodsynopsis>.*?<type>(.*?)</type>.*?<methodname>(.*?)</methodname>(.*?)</methodsynopsis>@s', $str, $tmp);
tmysik@6020
  1339
    if (!$methodsynopsis) {
tmysik@6020
  1340
        return $str;
tmysik@6020
  1341
    }
tmysik@6020
  1342
    $functionsDoc = array();
tmysik@6020
  1343
    $parameters = null;
tmysik@6020
  1344
    for ($i = 0; $i < count($tmp); ++$i) {
tmysik@6020
  1345
        $refname = trim($tmp[2][$i]);
tmysik@6020
  1346
        $functionsDoc[$refname]['methodname'] = $refname;
tmysik@6020
  1347
        $parameters = $tmp[3][$i];
tmysik@6020
  1348
        if ($parameters) {
tmysik@6020
  1349
                if (preg_match_all ('@<methodparam\s*(.*?)>.*?<type>(.*?)</type>.*?<parameter\s*(.*?)>(.*?)</parameter>(?:<initializer>(.+?)</initializer>)?.*?</methodparam>@s', $parameters, $match)) {
tmysik@6020
  1350
                        for ($i = 0; $i < count($match[0]); ++$i) {
tmysik@6020
  1351
                                $parameter = array (
tmysik@6020
  1352
                                        'type' => trim(str_replace('-', '_', $match[2][$i])), // e.g. OCI-Collection -> OCI_Collection
tmysik@6020
  1353
                                        'name' => clean_php_identifier(trim($match[4][$i])),
tmysik@6020
  1354
                                );
tmysik@6020
  1355
                                if (preg_match ('@choice=[\'"]opt[\'"]@', $match[1][$i])) {
tmysik@6020
  1356
                                        $parameter['isoptional'] = true;
tmysik@6020
  1357
                                }
tmysik@6020
  1358
                                if (preg_match ('@role=[\'"]reference[\'"]@', $match[3][$i])) {
tmysik@6020
  1359
                                        $parameter['isreference'] = true;
tmysik@6020
  1360
                                }
tmysik@6020
  1361
                                if (@strlen(trim($match[5][$i]))) {
tmysik@6020
  1362
                                        $parameter['defaultvalue'] = clean_php_value($match[5][$i]);
tmysik@6020
  1363
                                        $parameter['isoptional'] = true;
tmysik@6020
  1364
                                }
tmysik@6020
  1365
                                $functionsDoc[$refname]['parameters'][] = $parameter;
tmysik@6020
  1366
                        }
tmysik@6020
  1367
                }
tmysik@6020
  1368
                if (preg_match_all('@<varlistentry\s*.*?>.*?<parameter>(.*?)</parameter>.*?<listitem\s*.*?>(.*?)</listitem>.*?</varlistentry>@s', $parameters, $match)) {
tmysik@6020
  1369
                    for ($i = 0; $i < count($match[0]); $i++) {
tmysik@6020
  1370
                        for ($j = 0; $j < count(@$functionsDoc[$refname]['parameters']); $j++) {
tmysik@6020
  1371
                            if (clean_php_identifier(trim($match[1][$i])) == $functionsDoc[$refname]['parameters'][$j]['name']) {
tmysik@6020
  1372
                                $functionsDoc[$refname]['parameters'][$j]['paramdoc'] = xml_to_phpdoc ($match[2][$i]);
tmysik@6020
  1373
                                break;
tmysik@6020
  1374
                            }
tmysik@6020
  1375
                        }
tmysik@6020
  1376
                    }
tmysik@6020
  1377
                }
tmysik@6020
  1378
        }
tmysik@6020
  1379
    }
tmysik@6020
  1380
    return $str;
tmysik@6020
  1381
}
tmysik@6020
  1382
tmysik@6388
  1383
function parse_entities($phpdocDir, $lang) {
tmysik@6020
  1384
    $entities = array();
tmysik@6388
  1385
    parse_entities_from_file($entities, $phpdocDir, "/{$lang}/language-defs.ent");
tmysik@6388
  1386
    parse_entities_from_file($entities, $phpdocDir, "/{$lang}/language-snippets.ent");
tmysik@6020
  1387
    parse_entities_from_file($entities, $phpdocDir, '/doc-base/docbook/docbook-xml/ent/isonum.ent');
tmysik@6020
  1388
    parse_entities_from_file($entities, $phpdocDir, '/doc-base/entities/global.ent');
tmysik@6020
  1389
    return $entities;
tmysik@6020
  1390
}
tmysik@6020
  1391
function parse_entities_from_file(array &$entities, $phpdocDir, $filepath) {
tmysik@6020
  1392
    $content = file_get_contents($phpdocDir . $filepath);
tmysik@6020
  1393
    $matches = array();
tmysik@6020
  1394
    preg_match_all('%\!ENTITY\s+(\S+)\s+([\'"])([^\\2]+?)\\2\s*>%m', $content, $matches);
tmysik@6020
  1395
    if (array_key_exists(1, $matches) && count($matches[1])) {
tmysik@6020
  1396
        for ($i = 0; $i < count($matches[2]); $i++) {
tmysik@6020
  1397
            $entities['&' . $matches[1][$i] . ';'] = $matches[3][$i];
tmysik@6020
  1398
        }
tmysik@6020
  1399
    }
tmysik@6020
  1400
}
tmysik@6020
  1401
function replace_entities($text) {
tmysik@6020
  1402
    global $entities;
tmysik@6020
  1403
    $matches = array();
tmysik@6020
  1404
    while (preg_match_all('%(\&(?!#)\S+?\;)%', $text, $matches)) {
tmysik@6020
  1405
        if (count($matches[1])) {
tmysik@6020
  1406
            foreach ($matches[1] as $e) {
tmysik@6020
  1407
                $replace = null;
tmysik@6020
  1408
                if (array_key_exists($e, $entities)) {
tmysik@6020
  1409
                    $replace = $entities[$e];
tmysik@6020
  1410
                }
tmysik@6020
  1411
                if ($replace === null) {
tmysik@6020
  1412
                    switch ($e) {
tmysik@6020
  1413
                        case '&$a));':
tmysik@6020
  1414
                            // code sample
tmysik@6020
  1415
                        case '&reference.strings.charsets;':
tmysik@6100
  1416
                        case '&reference.intl.inctimezoneparam;':
tmysik@6100
  1417
                        case '&reference.intl.incfieldparam;':
tmysik@6020
  1418
                            // entity not found
tmysik@6020
  1419
                            break;
tmysik@6020
  1420
                        default:
tmysik@6020
  1421
                            die('Entity "' . $e . '" not found' . "\n");
tmysik@6020
  1422
                    }
tmysik@6020
  1423
                }
tmysik@6020
  1424
                $text = str_replace($e, $replace, $text);
tmysik@6020
  1425
            }
tmysik@6020
  1426
        }
tmysik@6020
  1427
    }
tmysik@6020
  1428
    // return back &lt; and &gt;
tmysik@6020
  1429
    $keep = array(
tmysik@6020
  1430
        '&#38;#60;' => '&lt;',
tmysik@6020
  1431
        '&#x0003E;' => '&gt;',
tmysik@6020
  1432
    );
tmysik@6020
  1433
    return str_replace(array_keys($keep), $keep, $text);
tmysik@6020
  1434
}
tmysik@6020
  1435
tmysik@6060
  1436
function parse_properties_from_html_file($filepath, $classname) {
tmysik@6060
  1437
    $file = DOC_URL . $filepath;
tmysik@6060
  1438
    if (!is_file($file)) {
tmysik@6060
  1439
        return array();
tmysik@6060
  1440
        //die('Cannot parse properties from non-existing file: ' . $file);
tmysik@6060
  1441
    }
tmysik@6060
  1442
    $fields = array();
tmysik@6060
  1443
    $html = new DOMDocument();
tmysik@6060
  1444
    $html->preserveWhiteSpace = false;
tmysik@6060
  1445
    @$html->loadHtmlFile($file);
tmysik@6060
  1446
    $xpath = new DOMXPath($html);
tmysik@6060
  1447
    // documentation
tmysik@6060
  1448
    $doc = array();
tmysik@6060
  1449
    $docNodes = $xpath->query('//div[@id="' . strtolower($classname) . '.props"]/dl');
tmysik@6060
  1450
    if (!$docNodes->length) {
tmysik@6060
  1451
        //die('Documentation not found for properties in file: ' . $file);
tmysik@6060
  1452
    } elseif ($docNodes->length > 1) {
tmysik@6060
  1453
        die('More documentations found for properties in file: ' . $file);
tmysik@6060
  1454
    }
tmysik@6060
  1455
    if ($docNodes->length) {
tmysik@6060
  1456
        $fieldname = null;
tmysik@6060
  1457
        foreach ($docNodes->item(0)->childNodes as $node) {
tmysik@6060
  1458
            if ($node->nodeName == 'dt') {
tmysik@6060
  1459
                $fieldname = trim($node->nodeValue);
tmysik@6060
  1460
            } elseif ($node->nodeName == 'dd') {
tmysik@6060
  1461
                $tmp = new DOMDocument();
tmysik@6060
  1462
                foreach ($node->childNodes as $child) {
tmysik@6060
  1463
                    $tmp->appendChild($tmp->importNode($child, true));
tmysik@6060
  1464
                }
tmysik@6060
  1465
                $doc[$fieldname] = $tmp->saveHTML();
tmysik@6060
  1466
            } else {
tmysik@6060
  1467
                //die('Unknown node name: ' . $node->nodeName);
tmysik@6060
  1468
            }
tmysik@6060
  1469
        }
tmysik@6060
  1470
    }
tmysik@6060
  1471
tmysik@6060
  1472
    // fields
tmysik@6060
  1473
    $fieldNodes = $xpath->query('//div[@class="classsynopsis"]//div[@class="fieldsynopsis"]');
tmysik@6060
  1474
    foreach ($fieldNodes as $fieldNode) {
tmysik@6060
  1475
        $field = new NetBeans_Field();
tmysik@6060
  1476
        // name
tmysik@6060
  1477
        $varnameNodes = $xpath->query('var//var[@class="varname"]', $fieldNode);
tmysik@6060
  1478
        if (!$varnameNodes->length) {
tmysik@6060
  1479
            die('Varname not found for property in file: ' . $file);
tmysik@6060
  1480
        } elseif ($varnameNodes->length > 1) {
tmysik@6060
  1481
            die('More varnames found for property in file: ' . $file);
tmysik@6060
  1482
        }
tmysik@6060
  1483
        $field->setName($varnameNodes->item(0)->nodeValue);
tmysik@6060
  1484
        // modifiers
tmysik@6060
  1485
        $modifierNodes = $xpath->query('span[@class="modifier"]', $fieldNode);
tmysik@6060
  1486
        foreach ($modifierNodes as $modifierNode) {
tmysik@6060
  1487
            $modifier = $modifierNode->nodeValue;
tmysik@6060
  1488
            // XXX
tmysik@6060
  1489
            if ($modifier == 'const') {
tmysik@6060
  1490
                // constant => do nothing
tmysik@6060
  1491
                return array();
tmysik@6060
  1492
            }
tmysik@6060
  1493
            $field->addModifier($modifier);
tmysik@6060
  1494
        }
tmysik@6060
  1495
        // type
tmysik@6060
  1496
        $typeNodes = $xpath->query('span[@class="type"]', $fieldNode);
tmysik@6060
  1497
        if ($typeNodes->length > 1) {
tmysik@6060
  1498
            die('More types found for property ' . $field->getName() . ' in file: ' . $file);
tmysik@6060
  1499
        }
tmysik@6060
  1500
        $field->setType($typeNodes->item(0)->nodeValue);
tmysik@6060
  1501
        // documentation
tmysik@6060
  1502
        if (array_key_exists($field->getName(), $doc)) {
tmysik@6060
  1503
            $field->setDocumentation($doc[$field->getName()]);
tmysik@6060
  1504
        }
tmysik@6060
  1505
        // all ok
tmysik@6060
  1506
        $fields[] = $field;
tmysik@6060
  1507
    }
tmysik@6060
  1508
    return $fields;
tmysik@6060
  1509
}
tmysik@6060
  1510
tmysik@6060
  1511
class NetBeans_Field {
tmysik@6060
  1512
tmysik@6060
  1513
    private $modifiers = array();
tmysik@6060
  1514
    private $type;
tmysik@6060
  1515
    private $name;
tmysik@6060
  1516
    private $value;
tmysik@6060
  1517
    private $documentation;
tmysik@6060
  1518
tmysik@6060
  1519
tmysik@6060
  1520
    public function getModifiers() {
tmysik@6060
  1521
        return $this->modifiers;
tmysik@6060
  1522
    }
tmysik@6060
  1523
tmysik@6060
  1524
    /**
tmysik@6060
  1525
     * @return \NetBeans_Field
tmysik@6060
  1526
     */
tmysik@6060
  1527
    public function addModifier($modifier) {
tmysik@6060
  1528
        $this->modifiers[] = $modifier;
tmysik@6060
  1529
        return $this;
tmysik@6060
  1530
    }
tmysik@6060
  1531
tmysik@6060
  1532
    /**
tmysik@6060
  1533
     * @return \NetBeans_Field
tmysik@6060
  1534
     */
tmysik@6060
  1535
    public function setModifiers($modifiers) {
tmysik@6060
  1536
        $this->modifiers = $modifiers;
tmysik@6060
  1537
        return $this;
tmysik@6060
  1538
    }
tmysik@6060
  1539
tmysik@6060
  1540
    public function getType() {
tmysik@6060
  1541
        return $this->type;
tmysik@6060
  1542
    }
tmysik@6060
  1543
tmysik@6060
  1544
    /**
tmysik@6060
  1545
     * @return \NetBeans_Field
tmysik@6060
  1546
     */
tmysik@6060
  1547
    public function setType($type) {
tmysik@6060
  1548
        $this->type = $type;
tmysik@6060
  1549
        return $this;
tmysik@6060
  1550
    }
tmysik@6060
  1551
tmysik@6060
  1552
    public function getName() {
tmysik@6060
  1553
        return $this->name;
tmysik@6060
  1554
    }
tmysik@6060
  1555
tmysik@6060
  1556
    /**
tmysik@6060
  1557
     * @return \NetBeans_Field
tmysik@6060
  1558
     */
tmysik@6060
  1559
    public function setName($name) {
tmysik@6060
  1560
        $this->name = $name;
tmysik@6060
  1561
        return $this;
tmysik@6060
  1562
    }
tmysik@6060
  1563
tmysik@6060
  1564
    public function getValue() {
tmysik@6060
  1565
        return $this->value;
tmysik@6060
  1566
    }
tmysik@6060
  1567
tmysik@6060
  1568
    /**
tmysik@6060
  1569
     * @return \NetBeans_Field
tmysik@6060
  1570
     */
tmysik@6060
  1571
    public function setValue($value) {
tmysik@6060
  1572
        $this->value = $value;
tmysik@6060
  1573
        return $this;
tmysik@6060
  1574
    }
tmysik@6060
  1575
tmysik@6060
  1576
    public function getDocumentation() {
tmysik@6060
  1577
        return $this->documentation;
tmysik@6060
  1578
    }
tmysik@6060
  1579
tmysik@6060
  1580
    /**
tmysik@6060
  1581
     * @return \NetBeans_Field
tmysik@6060
  1582
     */
tmysik@6060
  1583
    public function setDocumentation($documentation) {
tmysik@6060
  1584
        $this->documentation = trim($documentation);
tmysik@6060
  1585
        return $this;
tmysik@6060
  1586
    }
tmysik@6060
  1587
tmysik@6060
  1588
}
tmysik@6060
  1589
tmysik@6325
  1590
function sanitizeType($type) {
tmysik@6325
  1591
    if (!trim($type)) {
tmysik@6325
  1592
        return '';
tmysik@6325
  1593
    }
tmysik@6325
  1594
    if (strpos($type, '|') !== false) {
tmysik@6325
  1595
        // ignore 'MyClass|YourClass' cases
tmysik@6325
  1596
        return '';
tmysik@6325
  1597
    }
tmysik@6325
  1598
    if (in_array($type, [
tmysik@6325
  1599
        'mixed',
tmysik@6325
  1600
        'object',
tmysik@6325
  1601
        'callback',
tmysik@6325
  1602
        'resource',
tmysik@6325
  1603
        'bitmask',
tmysik@6325
  1604
        'name',
tmysik@6325
  1605
        'number',
tmysik@6325
  1606
        'scalar',
tmysik@6325
  1607
    ])) {
tmysik@6325
  1608
        return '';
tmysik@6325
  1609
    }
tmysik@6325
  1610
    $convert = [
tmysik@6325
  1611
        'boolean' => 'bool',
tmysik@6325
  1612
    ];
tmysik@6325
  1613
    return str_replace(array_keys($convert), $convert, $type);
tmysik@6325
  1614
}
tmysik@6325
  1615
tmysik@6325
  1616
function isConstant($value) {
tmysik@6325
  1617
    $values = explode(' | ', $value);
tmysik@6325
  1618
    foreach ($values as $v) {
tmysik@6325
  1619
        if (!preg_match('/^(\\w+\\:\\:)?[A-Z0-9_]+$/', $v)) {
tmysik@6325
  1620
            return false;
tmysik@6325
  1621
        }
tmysik@6325
  1622
    }
tmysik@6325
  1623
    return true;
tmysik@6325
  1624
}
tmysik@6325
  1625
tmysik@6020
  1626
/**
tmysik@6020
  1627
 * Prints usage help to the screen, and exits from program
tmysik@6020
  1628
 */
tmysik@6020
  1629
function show_help() {
tmysik@6020
  1630
	global $argv0;
tmysik@6020
  1631
tmysik@6020
  1632
	die (<<<EOF
tmysik@6020
  1633
USAGE: {$argv0} [options] <PHP.net documentation directory>
tmysik@6020
  1634
tmysik@6020
  1635
Where options are:
tmysik@6020
  1636
tmysik@6388
  1637
-help		Show this help.
tmysik@6388
  1638
-nosplit	Don't split output to different files.
tmysik@6388
  1639
-split		Split output to different files (one file per PHP extension).
tmysik@6388
  1640
-lang		Specify the language("en" by default). e.g. -lang en, -lang ja
tmysik@6388
  1641
-output 	Output directory name("php" by default).
tmysik@6020
  1642
tmysik@6020
  1643
EOF
tmysik@6020
  1644
	);
tmysik@6020
  1645
}
tmysik@6020
  1646
tmysik@6388
  1647
function show_message($message) {
tmysik@6388
  1648
	echo $message . PHP_EOL;
tmysik@6388
  1649
}
tmysik@6388
  1650
tmysik@6020
  1651
?>