mirror of
https://github.com/php/php-gtk-src.git
synced 2026-03-24 09:12:12 +01:00
with either old or new PHP build system. It also updates copyright years and fixes loading of rc files by test/gtk.php. Extension writers should take notice of the changes in the build system.
449 lines
12 KiB
PHP
449 lines
12 KiB
PHP
<?php
|
|
/*
|
|
* PHP-GTK - The PHP language bindings for GTK+
|
|
*
|
|
* Copyright (C) 2001,2002 Andrei Zmievski <andrei@php.net>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
/* $Id$ */
|
|
|
|
set_time_limit(300);
|
|
|
|
require "Getopt.php";
|
|
require "arg_types.php";
|
|
require "override.php";
|
|
require "scheme.php";
|
|
require "docmerger.php";
|
|
require "doc_templates.php";
|
|
|
|
class DocGenerator {
|
|
var $parser = null;
|
|
var $overrides = null;
|
|
var $prefix = null;
|
|
var $output_dir = null;
|
|
var $fp = null;
|
|
var $docmerger = null;
|
|
|
|
function DocGenerator(&$parser, &$overrides, &$docmerger, $prefix, $output_dir)
|
|
{
|
|
$this->parser = &$parser;
|
|
$this->overrides = &$overrides;
|
|
$this->docmerger = &$docmerger;
|
|
$this->prefix = $prefix;
|
|
if ($output_dir)
|
|
$this->output_dir = $output_dir;
|
|
else
|
|
$this->fp = fopen('php://stdout', 'w');
|
|
}
|
|
|
|
function create_docs($classes)
|
|
{
|
|
foreach ($classes as $key => $val)
|
|
$classes[$key] = strtolower($val);
|
|
|
|
function sort_objects($a, $b)
|
|
{
|
|
return strcmp($a->c_name, $b->c_name);
|
|
}
|
|
$parser_objects = $this->parser->objects;
|
|
usort($parser_objects, 'sort_objects');
|
|
|
|
foreach ($parser_objects as $object) {
|
|
$object_lcname = strtolower($object->in_module . $object->name);
|
|
if (count($classes) && !in_array($object_lcname, $classes))
|
|
continue;
|
|
|
|
if ($this->output_dir) {
|
|
print "Generating $object_lcname.xml...";
|
|
$this->fp = fopen($this->output_dir.'/'.$object_lcname.'.xml', 'w');
|
|
$this->write_class($object);
|
|
fclose($this->fp);
|
|
print "\n";
|
|
} else
|
|
$this->write_class($object);
|
|
}
|
|
|
|
if (count($classes) == 0) {
|
|
if ($this->output_dir) {
|
|
print "Generating ".$this->prefix."-functions.xml...";
|
|
$this->fp = fopen($this->output_dir.'/'.$this->prefix.'-functions.xml', 'w');
|
|
$this->write_functions();
|
|
fclose($this->fp);
|
|
print "\n";
|
|
} else
|
|
$this->write_functions();
|
|
}
|
|
}
|
|
|
|
function register_types($parser = null)
|
|
{
|
|
global $matcher;
|
|
|
|
if (!$parser)
|
|
$parser = $this->parser;
|
|
|
|
foreach ($parser->objects as $object)
|
|
$matcher->register_object($object->c_name);
|
|
|
|
foreach ($parser->enums as $enum) {
|
|
if ($enum->def_type == 'flags')
|
|
$matcher->register_flag($enum->c_name);
|
|
else
|
|
$matcher->register_enum($enum->c_name);
|
|
}
|
|
}
|
|
|
|
function write_class($object)
|
|
{
|
|
global $class_start_tpl,
|
|
$class_end_tpl,
|
|
$update_docs;
|
|
|
|
$object_name = $object->in_module . $object->name;
|
|
|
|
if($update_docs)
|
|
$this->docmerger->prepair($object_name);
|
|
|
|
fwrite($this->fp,
|
|
sprintf($class_start_tpl,
|
|
$this->prefix,
|
|
strtolower($object_name),
|
|
$object_name,
|
|
$object->parent[1] . $object->parent[0],
|
|
$update_docs?$this->docmerger->get_section_contents(NULL, CLASSENTRY, SHORTDESC):NULL,
|
|
$update_docs?$this->docmerger->get_section_contents(NULL, CLASSENTRY, DESC):NULL
|
|
));
|
|
|
|
$this->write_constructor($object);
|
|
$this->write_methods($object);
|
|
$this->write_properties($object);
|
|
if($update_docs)
|
|
fwrite($this->fp,
|
|
$this->docmerger->get_section_contents(NULL, SIGNALS, NULL));
|
|
|
|
fwrite($this->fp, $class_end_tpl);
|
|
}
|
|
|
|
function write_properties($object)
|
|
{
|
|
global $props_start_tpl,
|
|
$props_end_tpl;
|
|
|
|
if (count($object->fields) == 0)
|
|
return;
|
|
|
|
fwrite($this->fp, $props_start_tpl);
|
|
|
|
foreach ($object->fields as $field) {
|
|
$this->write_property($object, $field);
|
|
}
|
|
|
|
fwrite($this->fp, $props_end_tpl);
|
|
}
|
|
|
|
function write_property($object, $field)
|
|
{
|
|
global $prop_start_tpl,
|
|
$prop_end_tpl;
|
|
|
|
list($field_type, $field_name) = $field;
|
|
if (($doc_type = $this->get_type($field_type)) === false) {
|
|
$doc_type = 'XXX';
|
|
}
|
|
|
|
fwrite($this->fp, sprintf($prop_start_tpl, $this->prefix,
|
|
strtolower($object->in_module . $object->name),
|
|
$field_name, $field_name, $doc_type));
|
|
fwrite($this->fp, $prop_end_tpl);
|
|
}
|
|
|
|
function write_methods($object)
|
|
{
|
|
global $methods_start_tpl,
|
|
$methods_end_tpl;
|
|
|
|
$methods = $this->parser->find_methods($object);
|
|
if (count($methods))
|
|
fwrite($this->fp, $methods_start_tpl);
|
|
|
|
foreach ($methods as $method) {
|
|
if ($this->overrides->is_overriden($method->c_name)) {
|
|
$this->write_method($method, true);
|
|
} else if (!$this->overrides->is_ignored($method->c_name)) {
|
|
$this->write_method($method, false);
|
|
}
|
|
}
|
|
|
|
if (count($methods))
|
|
fwrite($this->fp, $methods_end_tpl);
|
|
}
|
|
|
|
function write_functions()
|
|
{
|
|
foreach ($this->parser->functions as $function) {
|
|
if ($this->overrides->is_overriden($function->c_name)) {
|
|
$this->write_method($function, true);
|
|
} else if (!$this->overrides->is_ignored($function->c_name)) {
|
|
$this->write_method($function, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
function write_constructor($object)
|
|
{
|
|
global $constructor_start_tpl,
|
|
$constructor_end_tpl,
|
|
$funcproto_tpl,
|
|
$no_parameter_tpl,
|
|
$update_docs;
|
|
|
|
$constructor = $this->parser->find_constructor($object);
|
|
|
|
if ($constructor) {
|
|
if ($this->overrides->is_overriden($constructor->c_name)) {
|
|
$overriden = true;
|
|
} else if (!$this->overrides->is_ignored($constructor->c_name)) {
|
|
$overriden = false;
|
|
} else
|
|
return;
|
|
} else
|
|
return;
|
|
|
|
if (!$overriden) {
|
|
if (($paramdef = $this->get_paramdef($constructor)) === false)
|
|
return;
|
|
}
|
|
|
|
$object_name = $constructor->is_constructor_of;
|
|
|
|
fwrite($this->fp,
|
|
sprintf($constructor_start_tpl,
|
|
$this->prefix,
|
|
strtolower($object_name)));
|
|
|
|
$funcdef = sprintf($funcproto_tpl,
|
|
'',
|
|
$object_name,
|
|
$overriden ? sprintf($no_parameter_tpl, 'XXX') : $paramdef);
|
|
fwrite($this->fp, preg_replace('!^ !m', '', $funcdef));
|
|
|
|
fwrite($this->fp,
|
|
sprintf($constructor_end_tpl,
|
|
$update_docs?$this->docmerger->get_section_contents(NULL, CONSTRUCTOR, SHORTDESC):NULL,
|
|
$update_docs?$this->docmerger->get_section_contents(NULL, CONSTRUCTOR, DESC):NULL
|
|
));
|
|
}
|
|
|
|
function write_method($method, $overriden)
|
|
{
|
|
global $method_start_tpl,
|
|
$method_func_start_tpl,
|
|
$method_end_tpl,
|
|
$funcproto_tpl,
|
|
$no_parameter_tpl,
|
|
$update_docs;
|
|
|
|
if (!$overriden) {
|
|
if (($paramdef = $this->get_paramdef($method)) === false ||
|
|
($return = $this->get_type($method->return_type)) === false)
|
|
return;
|
|
}
|
|
|
|
if (isset($method->of_object)) {
|
|
$object_name = $method->of_object[1] . $method->of_object[0];
|
|
|
|
fwrite($this->fp,
|
|
sprintf($method_start_tpl,
|
|
$this->prefix,
|
|
strtolower($object_name),
|
|
$method->name));
|
|
} else
|
|
fwrite($this->fp,
|
|
sprintf($method_func_start_tpl,
|
|
$this->prefix,
|
|
$method->name));
|
|
|
|
fwrite($this->fp,
|
|
sprintf($funcproto_tpl,
|
|
$overriden ? 'XXX' : $return,
|
|
$method->name,
|
|
$overriden ? sprintf($no_parameter_tpl, 'XXX') : $paramdef));
|
|
|
|
fwrite($this->fp,
|
|
sprintf($method_end_tpl,
|
|
$update_docs?$this->docmerger->get_section_contents($method->name, METHOD, SHORTDESC):NULL,
|
|
$update_docs?$this->docmerger->get_section_contents($method->name, METHOD, DESC):NULL
|
|
));
|
|
}
|
|
|
|
function get_paramdef($function)
|
|
{
|
|
global $matcher,
|
|
$parameter_tpl,
|
|
$no_parameter_tpl,
|
|
$opt_parameter_tpl;
|
|
|
|
if ($function->varargs)
|
|
return false;
|
|
|
|
foreach ($function->params as $params_array) {
|
|
list($param_type, $param_name, $param_default, $param_null) = $params_array;
|
|
|
|
if (($doc_type = $this->get_type($param_type)) === false)
|
|
return false;
|
|
|
|
if (isset($param_default))
|
|
$paramdef .= sprintf($opt_parameter_tpl, $doc_type, $param_name, $param_default);
|
|
else
|
|
$paramdef .= sprintf($parameter_tpl, $doc_type, $param_name);
|
|
}
|
|
|
|
return $paramdef ? $paramdef : sprintf($no_parameter_tpl, 'void');
|
|
}
|
|
|
|
function get_type($in_type)
|
|
{
|
|
global $matcher;
|
|
static $type_map =
|
|
array('none' => 'void',
|
|
|
|
'char*' => 'string',
|
|
'gchar*' => 'string',
|
|
'const-char*' => 'string',
|
|
'const-gchar*' => 'string',
|
|
'string' => 'string',
|
|
'static_string' => 'string',
|
|
'unsigned-char*' => 'string',
|
|
'guchar*' => 'string',
|
|
|
|
'char' => 'char',
|
|
'gchar' => 'char',
|
|
'guchar' => 'char',
|
|
|
|
'int' => 'int',
|
|
'gint' => 'int',
|
|
'guint' => 'int',
|
|
'short' => 'int',
|
|
'gshort' => 'int',
|
|
'gushort' => 'int',
|
|
'long' => 'int',
|
|
'glong' => 'int',
|
|
'gulong' => 'int',
|
|
|
|
'guint8' => 'int',
|
|
'gint8' => 'int',
|
|
'guint16' => 'int',
|
|
'gint16' => 'int',
|
|
'guint32' => 'int',
|
|
'gint32' => 'int',
|
|
'GtkType' => 'int',
|
|
|
|
'gboolean' => 'bool',
|
|
|
|
'double' => 'double',
|
|
'gdouble' => 'double',
|
|
'float' => 'double',
|
|
'gfloat' => 'double',
|
|
|
|
'GdkDrawable*' => 'GdkWindow');
|
|
|
|
$type_handler = &$matcher->get($in_type);
|
|
if ($type_handler === null)
|
|
return false;
|
|
|
|
if (isset($type_map[$in_type]))
|
|
return $type_map[$in_type];
|
|
else {
|
|
$in_type = str_replace('*', '', $in_type);
|
|
$type_handler_class = get_class($type_handler);
|
|
if ($type_handler_class == 'object_arg' ||
|
|
$type_handler_class == 'boxed_arg')
|
|
return "<classname>$in_type</classname>";
|
|
else if ($type_handler_class == 'enum_arg' ||
|
|
$type_handler_class == 'flags_arg')
|
|
return "<enumname>$in_type</enumname>";
|
|
else
|
|
return $in_type;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* For backwards compatibility. */
|
|
chdir(dirname(__FILE__));
|
|
|
|
$argc = $HTTP_SERVER_VARS['argc'];
|
|
$argv = $HTTP_SERVER_VARS['argv'];
|
|
|
|
/* An ugly hack to counteract PHP's pernicious desire to treat + as an argument
|
|
separator in command-line version. */
|
|
array_walk($argv, create_function('&$x', '$x = urldecode($x);'));
|
|
|
|
$result = Console_Getopt::getopt($argv, 'o:p:r:d:s:l:u');
|
|
if (!$result || count($result[1]) < 2)
|
|
die(
|
|
"Usage: php -q generator.php [OPTION] defsfile [class ...]
|
|
|
|
-o <file> use overrides in <file>
|
|
-p <prefix> use <prefix> for docs
|
|
-r <file> register types from <file>
|
|
-d <path> output files to this directory
|
|
-s <path> documentation dir
|
|
-l <lang> Language
|
|
-u Update existing docs
|
|
");
|
|
|
|
list($opts, $argv) = $result;
|
|
|
|
$prefix = 'gtk';
|
|
$overrides = new Overrides();
|
|
$lang = 'en';
|
|
$update_docs = FALSE;
|
|
|
|
foreach ($opts as $opt) {
|
|
list($opt_spec, $opt_arg) = $opt;
|
|
if ($opt_spec == 'o') {
|
|
$overrides = new Overrides($opt_arg);
|
|
} else if ($opt_spec == 'p') {
|
|
$prefix = $opt_arg;
|
|
} else if ($opt_spec == 'r') {
|
|
$type_parser = new Defs_Parser($opt_arg);
|
|
$type_parser->start_parsing();
|
|
DocGenerator::register_types($type_parser);
|
|
} else if ($opt_spec == 'd') {
|
|
$output_dir = $opt_arg;
|
|
} else if ($opt_spec == 's') {
|
|
$docs_dir = $opt_arg;
|
|
} else if ($opt_spec == 'l') {
|
|
$lang = $opt_arg;
|
|
} else if ($opt_spec == 'u') {
|
|
$update_docs = TRUE;
|
|
}
|
|
}
|
|
|
|
$parser = new Defs_Parser($argv[1]);
|
|
|
|
if($update_docs)
|
|
$docmerger = new DocMerger($docs_dir, $lang, $prefix);
|
|
|
|
$generator = new DocGenerator($parser, $overrides, $docmerger, $prefix, $output_dir);
|
|
|
|
$parser->start_parsing();
|
|
$generator->register_types();
|
|
$generator->create_docs(array_slice($argv, 2));
|
|
|
|
?>
|