goba Sun Oct 27 05:02:55 2002 EDT Modified files: /phpdoc/scripts xml_proto.php Log: Adding code sent by Brad House
Index: phpdoc/scripts/xml_proto.php diff -u phpdoc/scripts/xml_proto.php:1.3 phpdoc/scripts/xml_proto.php:1.4 --- phpdoc/scripts/xml_proto.php:1.3 Thu Oct 24 17:48:43 2002 +++ phpdoc/scripts/xml_proto.php Sun Oct 27 05:02:55 2002 @@ -16,19 +16,58 @@ # | Authors: Brad House <[EMAIL PROTECTED]> | # +----------------------------------------------------------------------+ # -# $Id: xml_proto.php,v 1.3 2002/10/24 21:48:43 philip Exp $ +# $Id: xml_proto.php,v 1.4 2002/10/27 10:02:55 goba Exp $ */ /* - This program generates XML files for functions implemented in a PHP - extension with documented protos.Pass the PHP extension.c file to - the script, and it will write out a number of files based on the - protos in the C source. + REQUIRES: PHP 4.3.0-pre1 or higher + + This program generates XML documentation from the C source code + of the extension. For functions, the code _must_ have protos, + for constants, the raw source code will be read and interpretted + to generate the constants.xml file + + XML_PROTO v2.0 : Generate PHP documentation from proto defs (req PHP 4.3.0-pre1+) + Usage: php xml_proto.php [opts] <extension name> <files to parse> + Ex: php xml_proto.php mcve /php4/ext/mcve/*.c + + Options: + -C : generate only constants.xml file (in current directory) + -F : generate only fuction reference files (all will be placed in current +directory) + -A : (default) generate full documentation template + This will generate <extension name>/ directory which reference.xml and +contents.xml + will be created in, and a subdirectory <extension name>/functions/ which all + function xml reference files will be generated in +*/ + +/* CHANGELOG: + 10/??/02 v1.0 - Original Release + 10/??/02 v1.1 - replace & with & + 10/??/02 v1.2 - the Revision would be changed in static text meant for + insert into generated XML files (CVS did it) + 10/26/02 v2.0 - Additional scanning for constants, and generation of constants.xml + - Generation of references.xml template + - functions with optional arguments would not parse properly, now it +does + - Wildcard scanning is now allowed + - Requires PHP 4.3.0-pre1 or higher now + - Usage is totally different */ +$version="2.0"; + $funclist=array(); $num_funcs=0; +$constlist=array(); +$num_const=0; + +$generate_constants=1; +$generate_functions=1; +$source_files=array(); +$extension_name=""; +$constant_dir=""; +$function_dir=""; + function new_function() { global $funclist, $num_funcs; @@ -77,27 +116,92 @@ return(1); } -function function_add_arg($num, $type, $argname) +function function_add_arg($num, $type, $argname, $isopt) { global $funclist, $num_funcs; $num_args=$funclist[$num]["num_args"]; $funclist[$num]["args"][$num_args]["type"]=$type; $funclist[$num]["args"][$num_args]["variable"]=$argname; + $funclist[$num]["args"][$num_args]["isopt"]=$isopt; $funclist[$num]["num_args"]++; return(1); } -function write_xml_files() +function write_reference_xml() +{ + global $extension_name, $constant_dir, $version; + + $filename= $constant_dir. "reference.xml"; + $fp=fopen($filename, "wb"); + if (!$fp) { + echo "Failed writing: $filename\n"; + return(0); + } + + fwrite($fp, "<?xml version='1.0' encoding='iso-8859-1'?>\n" . + "<!-- $" . "Revision: 1.1 " . "$ -->\n" . + "<!-- Generated by xml_proto.php v" . $version . ". Found in /scripts +directory of phpdoc. -->\n" . + " <reference id=\"ref." . $extension_name . "\">\n" . + " <title>$extension_name Functions</title>\n" . + " <titleabbrev>$extension_name</titleabbrev>\n" . + "\n" . + " <partintro>\n" . + " <section id=\"" . $extension_name . ".intro\">\n" . + " &reftitle.intro;\n" . + " <para>\n" . + " This is the " . $extension_name . " extension. It\n" . + " currently only lists the proto definitions.\n" . + " </para>\n" . + " </section>\n" . + " <section id=\"" . $extension_name . ".installation\">\n" . + " &reftitle.install;\n" . + " <para>\n" . + " To be written. Probably running configure with the\n" . + " <option role=\"configure\">--with-" . $extension_name . "</option>\n" . + " will properly enable this module.\n" . + " </para>\n" . + " </section>\n" . + " </partintro>\n" . + " &reference.mcve.functions;\n" . + " </reference>\n" . + "<!-- Keep this comment at the end of the file\n" . + "Local variables:\n" . + "mode: sgml\n" . + "sgml-omittag:t\n" . + "sgml-shorttag:t\n" . + "sgml-minimize-attributes:nil\n" . + "sgml-always-quote-attributes:t\n" . + "sgml-indent-step:1\n" . + "sgml-indent-data:t\n" . + "indent-tabs-mode:nil\n" . + "sgml-parent-document:nil\n" . + "sgml-default-dtd-file:\"../../../manual.ced\"\n" . + "sgml-exposed-tags:nil\n" . + "sgml-local-catalogs:nil\n" . + "sgml-local-ecat-files:nil\n" . + "End:\n" . + "vim600: syn=xml fen fdm=syntax fdl=2 si\n" . + "vim: et tw=78 syn=sgml\n" . + "vi: ts=1 sw=1\n" . + "-->\n"); + fclose($fp); + + echo "Wrote: $filename\n"; + return(1); +} + +function write_functions_xml() { global $funclist, $num_funcs; + global $function_dir, $version; $filename=""; $fp=0; for ($i=0; $i<$num_funcs; $i++) { - $filename= $funclist[$i]["function_name_fix"] . ".xml"; + $filename= $function_dir . $funclist[$i]["function_name_fix"] . ".xml"; $fp=fopen($filename, "wb"); if (!$fp) { echo "Failed writing: $filename\n"; @@ -109,8 +213,9 @@ $functype=$funclist[$i]["function_type"]; fwrite($fp, "<?xml version='1.0' encoding='iso-8859-1'?>\n" . - '<!-- $' . "Revision: 1.1 $ -->\n" . - " <refentry id=\"function." . $fixname . "\">\n" . + "<!-- $" . "Revision: 1.1 $ -->\n" . + "<!-- Generated by xml_proto.php v" . $version . ". Found in /scripts +directory of phpdoc. -->\n" . + " <refentry id=\"function." . $fixname . "\">\n" . " <refnamediv>\n" . " <refname>$funcname</refname>\n" . " <refpurpose>$purpose</refpurpose>\n" . @@ -123,7 +228,13 @@ for ($j=0; $j<$funclist[$i]["num_args"]; $j++) { $argtype = $funclist[$i]["args"][$j]["type"]; $argname = str_replace('&', '&', $funclist[$i]["args"][$j]["variable"]); - fwrite($fp, " <methodparam><type>$argtype</type><parameter>$argname</parameter></methodparam>\n"); + $isopt=$funclist[$i]["args"][$j]["isopt"]; + if (!$isopt) { + fwrite($fp, " +<methodparam><type>$argtype</type><parameter>$argname</parameter></methodparam>\n"); + } else { + fwrite($fp, " <methodparam +choice=\"opt\"><type>$argtype</type><parameter>$argname</parameter></methodparam>\n"); + + } } if ($funclist[$i]["num_args"] == 0){ fwrite($fp, " <void/>\n"); @@ -223,6 +334,7 @@ $temp=""; $temp2=""; $temp_len=0; + $isopt=0; $len=strlen($proto); @@ -235,7 +347,8 @@ if ($temp_len) { if (!$got_proto_def) { if (strcasecmp($temp, "proto") != 0) { - echo "Not a proper proto definition: $proto\n"; + // Possibly just a comment, don't output error info + // echo "Not a proper proto definition: $proto\n"; return(0); } else { $got_proto_def=1; @@ -252,13 +365,28 @@ $temp2=$temp; } else if ($start_args && $got_arg_type) { $got_arg_type=0; - function_add_arg($func_number, $temp2, $temp); + function_add_arg($func_number, $temp2, $temp, $isopt); $temp2=""; } $temp_len=0; $temp=""; } break; + + case '[': + if ($got_proto_name) { + $isopt=1; + } else { + echo "Not a proper proto definition -5: $proto\n"; + } + break; + + case ']': + if ($got_proto_name && $isopt) { + } else { + echo "Not a proper proto definition -6: $proto\n"; + } + break; case '(': if ($got_proto_type && $got_proto_def &&!$got_proto_name) { @@ -277,7 +405,7 @@ case ')': if ($start_args) { if ($got_arg_type && $temp_len) { - function_add_arg($func_number, $temp2, $temp); + function_add_arg($func_number, $temp2, $temp, $isopt); $temp=""; $temp_len=0; } @@ -291,12 +419,12 @@ case ',': if ($start_args && $got_arg_type) { $got_arg_type=0; - function_add_arg($func_number, $temp2, $temp); + function_add_arg($func_number, $temp2, $temp, $isopt); $temp2=""; $temp=""; $temp_len=0; - } else { - echo "Not a proper proto definition -3: $proto\n"; + } else if ($temp && !$temp2) { + echo "Not a proper proto definition -3: $temp2 : $temp : $proto\n"; return(0); } break; @@ -339,25 +467,301 @@ return(1); } -function create_xml_docs($filename) +function add_constant_to_list($name, $type) { - $contents=read_file($filename); - if ($contents == false || $contents == "") { - echo "Could not read $filename\n"; + global $constlist; + global $num_const; + + $constlist[$num_const]["name"]=$name; + $constlist[$num_const]["type"]=$type; + $num_const++; + return(1); +} + +function add_constant($varlist, $type) +{ + $on_name=0; + $len=strlen($varlist); + for ($i=0; $i<$len; $i++) { + $c=substr($varlist, $i, 1); + switch($c) { + case '"'; + if (!$on_name) { + $on_name=1; + $name=""; + } else { + $on_name=0; + add_constant_to_list($name, $type); + return(1); + } + break; + + case ',': + return(0); + break; + + default: + if ($on_name) { + $name .= $c; + } + break; + + } + } + return(0); +} + +function scan_for_constants_byref($buffer, $string, $type) +{ + $ptr=$buffer; + + while (1) { + $temp=stristr($ptr, $string); + if (!$temp) { return(1); } + $temp2=substr($temp, strlen($string), strlen($temp)-strlen($string)); + $temp3=stristr($temp2, "("); + if (!$temp3) { return(1); } + $temp4=substr($temp3, 1, strlen($temp3)-1); + $temp5=stristr($temp4, ")"); + if (!$temp5) { return(1); } + $varlist=substr($temp4, 0, strlen($temp4)-strlen($temp5)); + if (!add_constant($varlist, $type)) { + echo "Invalid constant definition: "; + $str=substr($temp, 0, strlen($temp)-strlen($temp5)+1); + echo $str; + echo "\n"; + } + $ptr=$temp5; } - parse_file($contents); - write_xml_files(); + return(0); +} + +function scan_for_constants($buffer) +{ + scan_for_constants_byref($buffer, "REGISTER_LONG_CONSTANT", "long"); + scan_for_constants_byref($buffer, "REGISTER_DOUBLE_CONSTANT", "double"); + scan_for_constants_byref($buffer, "REGISTER_STRING_CONSTANT", "string"); +} + +function write_constants_xml() +{ + global $constant_dir; + global $constlist; + global $num_const; + global $extension_name; + global $version; + + if ($num_const == 0) { + echo "No constants found, aborting write of constants.xml\n"; + return(1); + } + + $filename = $constant_dir . "constants.xml"; + $fp=fopen($filename, "wb"); + if (!$fp) { + echo "Failed writing: $filename\n"; + return(0); + } + + fwrite($fp, "<?xml version='1.0' encoding='iso-8859-1'?>\n" . + "<!-- $" . "Revision: 1.1 $ -->\n" . + "<!-- Generated by xml_proto.php v" . $version . ". Found in /scripts +directory of phpdoc. -->\n" . + "<section id=\"" . $extension_name . ".constants\">\n" . + " &reftitle.constants;\n" . + " &extension.constants;\n" . + " <variablelist>\n"); + for ($i=0; $i<$num_const; $i++) { + $type=$constlist[$i]["type"]; + if (strcasecmp($type, "long") == 0) { + $linkend="language.types.integer"; + } else if (strcasecmp($type, "double") == 0) { + $linkend="language.types.double"; + } else if (strcasecmp($type, "string") == 0) { + $linkend="language.types.string"; + } + fwrite($fp, " <varlistentry>\n" . + " <term>\n" . + " <constant>" . $constlist[$i]["name"] . "</constant>\n" . + " (<link linkend=\"" . $linkend . "\">" . $type . "</link>)\n" . + " </term>\n" . + " <listitem>\n" . + " <simpara>\n" . + "\n" . + " </simpara>\n" . + " </listitem>\n" . + " </varlistentry>\n"); + } + + fwrite($fp, "\n" . + "<!-- Keep this comment at the end of the file\n" . + "Local variables:\n" . + "mode: sgml\n" . + "sgml-omittag:t\n" . + "sgml-shorttag:t\n" . + "sgml-minimize-attributes:nil\n" . + "sgml-always-quote-attributes:t\n" . + "sgml-indent-step:1\n" . + "sgml-indent-data:t\n" . + "indent-tabs-mode:nil\n" . + "sgml-parent-document:nil\n" . + "sgml-default-dtd-file:\"../../../../manual.ced\"\n" . + "sgml-exposed-tags:nil\n" . + "sgml-local-catalogs:nil\n" . + "sgml-local-ecat-files:nil\n" . + "End:\n" . + "vim600: syn=xml fen fdm=syntax fdl=2 si\n" . + "vim: et tw=78 syn=sgml\n" . + "vi: ts=1 sw=1\n" . + "-->\n"); + fclose($fp); + + echo "Wrote: $filename\n"; + return(1); +} + +function create_xml_docs() +{ + global $source_files, $generate_constants, $generate_functions; + global $funclist, $num_funcs; + $num=count($source_files); + + for ($i=0; $i<$num; $i++) { + echo "READING " . $source_files[$i] . "\n"; + $contents=read_file($source_files[$i]); + if ($contents == false || $contents == "") { + echo "Could not read $filename\n"; + } + if ($generate_functions) { + parse_file($contents); + } + if ($generate_constants) { + echo "Scanning for constants\n"; + scan_for_constants($contents); + } + } + + + if ($generate_functions) { + echo "Writing function XML files\n"; + write_functions_xml(); + } + + if ($generate_constants) { + echo "Writing constants XML file\n"; + write_constants_xml(); + } + + if ($generate_constants && $generate_functions) { + echo "Writing reference XML file\n"; + write_reference_xml(); + } + + return(1); +} + +function minimum_version($vercheck) { + $minver = explode(".", $vercheck); + $curver = explode(".", phpversion()); + if (($curver[0] < $minver[0]) || (($curver[0] = $minver[0]) && ($curver[1] < +$minver[1])) || + (($curver[0] = $minver[0]) && ($curver[1] = $minver[1]) && ($curver[2][0] < +$minver[2][0]))) { + return false; + } else { + return true; + } +} + +function usage($progname) +{ + global $version; + echo "XML_PROTO v$version : Generate PHP documentation from proto defs (req PHP +4.3.0-pre1+)\n"; + echo "Usage: " . $progname . " [opts] <extension name> <files to parse>\n"; + echo " Ex: " . $progname . " mcve /php4/ext/mcve/*.c\n\n"; + echo "Options:\n"; + echo " -C : generate only constants.xml file (in current directory)\n"; + echo " -F : generate only fuction reference files (all will be placed in current +directory)\n"; + echo " -A : (default) generate full documentation template\n"; + echo " This will generate <extension name>/ directory which reference.xml and +contents.xml\n"; + echo " will be created in, and a subdirectory <extension name>/functions/ +which all\n"; + echo " function xml reference files will be generated in\n\n"; + echo "Note: If you are documenting a new extension, you will need to add a new +line\n"; + echo " to the /manual.xml.in file under the <part id=\"funcref\"> section +following\n"; + echo " the format \"&reference.<extension name>.reference;\", but please +try\n"; + echo " to maintain the alphabetical order!\n\n"; +} + +function parse_cli($progargc, $progargv) +{ + global $generate_constants, $generate_functions, $extension_name; + global $constant_dir, $function_dir, $source_files; + + $unknown_arg=0; + + for ($i=1; $i<$progargc; $i++) { + if (strcasecmp($progargv[$i], "-C") == 0) { + $generate_constants=1; + $generate_functions=0; + } else if (strcasecmp($progargv[$i], "-F") == 0) { + $generate_functions=1; + $generate_constants=0; + } else if (strcasecmp($progargv[$i], "-A") == 0) { + $generate_functions=1; + $generate_constants=1; + } else { + if ($unknown_arg == 0) { + $extension_name=$progargv[$i]; + if ($generate_functions && $generate_constants) { + $constant_dir="./$extension_name/"; + $function_dir="./$extension_name/functions/"; + } + } else { + $temp_source_files=glob($progargv[$i]); + $num=count($source_files); + $new_num=count($temp_source_files); + for ($j=0; $j<$new_num; $j++) { + $source_files[$num+$j]=$temp_source_files[$j]; + } + $total=count($source_files); + } + $unknown_arg++; + } + } + return(1); } $myargc=$_SERVER["argc"]; $myargv=$_SERVER["argv"]; -if ($myargc < 2) { - echo "Usage: " . $myargv[0] . " <extension.c>\n"; - exit(1); +if (!minimum_version("4.3.0")) { + echo "You need PHP 4.3.0-pre1 or higher!\n"; + $ver=phpversion(); + echo "YOU HAVE: $ver\n"; + exit(); } -create_xml_docs($myargv[1]); +if ($myargc < 3) { + usage($myargv[0]); + exit(); +} + +if (!parse_cli($myargc, $myargv)) { + usage($myargv[0]); + exit(); +} + +/* Generating it all, create directory structure */ +if ($generate_constants && $generate_functions) { + mkdir("./" . $extension_name); + mkdir("./" . $extension_name . "/functions"); +} + +create_xml_docs(); + echo "\n"; + echo "Note: If you are documenting a new extension, you will need to add a new +line\n"; + echo " to the /manual.xml.in file under the <part id=\"funcref\"> section +following\n"; + echo " the format \"&reference.<extension name>.reference;\", but please +try\n"; + echo " to maintain the alphabetical order!\n\n"; + ?> +
-- PHP Documentation Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php