It no longer includes a way to generate XML documentation (the PHP documentation utilities already got tools for that in svn under phpdoc/doc-base) and it no longer support function stubs.
$ php ext_skel.php --help
php ext_skel.php --ext=<name> [--experimental] [--author=<name>]
[--dir=<path>] [--std] [--onlyunix]
[--onlywindows] [--help]
--ext=<name> The name of the extension defined as <name>
--experimental Passed if this extension is experimental, this creates
the EXPERIMENTAL file in the root of the extension
--author=<name> Your name, this is used if --header is passed and
for the CREDITS file
--dir=<path> Path to the directory for where extension should be
created. Defaults to the directory of where this script
lives
--std If passed, the standard header and vim rules footer used
in extensions that is included in the core, will be used
--onlyunix Only generate configure scripts for Unix
--onlywindows Only generate configure scripts for Windows
--help This help
Example usage:
$ php ext_skel.php --ext test --std --experimental
$ php ext_skel.php --ext kalle --author "Kalle Sommer Nielsen"
$ php ext_skel.php --ext phpfi --dir "/home/kalle/dev/" --onlyunix
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.0alpha1
-- Session:
- . Fixed bug #74941 (session fails to start after having headers sent).
- (morozov)
+- Core:
+ . Redesigned the old ext_skel program written in PHP, run:
+ 'php ext_skel.php' for all options. This means there is no dependencies
+ thrus making it work on Windows out of the box. (Kalle)
- LDAP:
- . Added ldap_exop_refresh helper for EXOP REFRESH operation with dds overlay
+ . Added ldap_exop_refresh helper for EXOP REFRESH operation with dds overlay.
+ (Côme)
- ODBC:
. Removed support for Birdstep. (Kalle)
+- Session:
+ . Fixed bug #74941 (session fails to start after having headers sent).
+ (morozov)
+
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
1. Backward Incompatible Changes
========================================
+Core:
+ . The ext_skel utility has been completely redesigned with new options and
+ some old options removed. This is now written in PHP and have no external
+ dependencies.
+
========================================
2. New Features
========================================
+++ /dev/null
-#!/bin/sh
-
-givup() {
- echo $*
- exit 1
-}
-
-usage() {
-echo "$0 --extname=module [--proto=file] [--stubs=file] [--xml[=file]]"
-echo " [--skel=dir] [--full-xml] [--no-help]"
-echo ""
-echo " --extname=module module is the name of your extension"
-echo " --proto=file file contains prototypes of functions to create"
-echo " --stubs=file generate only function stubs in file"
-echo " --xml generate xml documentation to be added to phpdoc-svn"
-echo " --skel=dir path to the skeleton directory"
-echo " --full-xml generate xml documentation for a self-contained extension"
-echo " (not yet implemented)"
-echo " --no-help don't try to be nice and create comments in the code"
-echo " and helper functions to test if the module compiled"
-exit 1
-}
-
-if test $# = 0; then
- usage
-fi
-
-while test $# -gt 0; do
- case "$1" in
- -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) optarg= ;;
- esac
-
- case $1 in
- --extname=?*)
- extname=$optarg
- EXTNAME=`echo $extname | tr "[:lower:]" "[:upper:]"`
- ;;
- --proto=?*)
- proto=$optarg
- ;;
- --stubs=*)
- stubs=yes
- stubfile=$optarg
- ;;
- --xml)
- xml="yes"
- ;;
- --xml=?*)
- xml=$optarg
- ;;
- --full-xml)
- full_xml="yes"
- ;;
- --no-help)
- no_help="yes"
- ;;
- --skel=?*)
- skel_dir=$optarg
- ;;
- *)
- usage
- ;;
- esac
- shift
-done
-
-if test -d "$extname" ; then
- givup "Directory $extname already exists."
-fi
-
-if test -z "$skel_dir"; then
- skel_dir="skeleton"
-fi
-
-## convert skel_dir to full path
-skel_dir=`cd $skel_dir && pwd`
-
-test -d $skel_dir || givup "directory $skel_dir does not exist or is not directory"
-
-if echo '\c' | grep -s c >/dev/null 2>&1
-then
- ECHO_N="echo -n"
- ECHO_C=""
-else
- ECHO_N="echo"
- ECHO_C='\c'
-fi
-
-if test -z "$stubs"; then
- echo "Creating directory $extname"
- stubfile=$extname"/function_stubs"
- mkdir $extname || givup "Cannot create directory $extname"
-fi
-
-if test -n "$proto"; then
- cat $proto | awk -v extname=$extname -v stubs=$stubs -v stubfile=$stubfile -v xml=$xml -v full_xml=$full_xml -v i_know_what_to_do_shut_up_i_dont_need_your_help_mode=$no_help -f $skel_dir/create_stubs
-fi
-
-if test -z "$stubs"; then
- cd $extname
- chmod 755 .
-
-$ECHO_N "Creating basic files:$ECHO_C"
-
-$ECHO_N " config.m4$ECHO_C"
-cat >config.m4 <<eof
-dnl \$Id\$
-dnl config.m4 for extension $extname
-
-dnl Comments in this file start with the string 'dnl'.
-dnl Remove where necessary. This file will not work
-dnl without editing.
-
-dnl If your extension references something external, use with:
-
-dnl PHP_ARG_WITH($extname, for $extname support,
-dnl Make sure that the comment is aligned:
-dnl [ --with-$extname Include $extname support])
-
-dnl Otherwise use enable:
-
-dnl PHP_ARG_ENABLE($extname, whether to enable $extname support,
-dnl Make sure that the comment is aligned:
-dnl [ --enable-$extname Enable $extname support])
-
-if test "\$PHP_$EXTNAME" != "no"; then
- dnl Write more examples of tests here...
-
- dnl # --with-$extname -> check with-path
- dnl SEARCH_PATH="/usr/local /usr" # you might want to change this
- dnl SEARCH_FOR="/include/$extname.h" # you most likely want to change this
- dnl if test -r \$PHP_$EXTNAME/\$SEARCH_FOR; then # path given as parameter
- dnl ${EXTNAME}_DIR=\$PHP_$EXTNAME
- dnl else # search default path list
- dnl AC_MSG_CHECKING([for $extname files in default path])
- dnl for i in \$SEARCH_PATH ; do
- dnl if test -r \$i/\$SEARCH_FOR; then
- dnl ${EXTNAME}_DIR=\$i
- dnl AC_MSG_RESULT(found in \$i)
- dnl fi
- dnl done
- dnl fi
- dnl
- dnl if test -z "\$${EXTNAME}_DIR"; then
- dnl AC_MSG_RESULT([not found])
- dnl AC_MSG_ERROR([Please reinstall the $extname distribution])
- dnl fi
-
- dnl # --with-$extname -> add include path
- dnl PHP_ADD_INCLUDE(\$${EXTNAME}_DIR/include)
-
- dnl # --with-$extname -> check for lib and symbol presence
- dnl LIBNAME=$extname # you may want to change this
- dnl LIBSYMBOL=$extname # you most likely want to change this
-
- dnl PHP_CHECK_LIBRARY(\$LIBNAME,\$LIBSYMBOL,
- dnl [
- dnl PHP_ADD_LIBRARY_WITH_PATH(\$LIBNAME, \$${EXTNAME}_DIR/\$PHP_LIBDIR, ${EXTNAME}_SHARED_LIBADD)
- dnl AC_DEFINE(HAVE_${EXTNAME}LIB,1,[ ])
- dnl ],[
- dnl AC_MSG_ERROR([wrong $extname lib version or lib not found])
- dnl ],[
- dnl -L\$${EXTNAME}_DIR/\$PHP_LIBDIR -lm
- dnl ])
- dnl
- dnl PHP_SUBST(${EXTNAME}_SHARED_LIBADD)
-
- PHP_NEW_EXTENSION($extname, $extname.c, \$ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
-fi
-eof
-
-$ECHO_N " config.w32$ECHO_C"
-cat >config.w32 <<eof
-// \$Id\$
-// vim:ft=javascript
-
-// If your extension references something external, use ARG_WITH
-// ARG_WITH("$extname", "for $extname support", "no");
-
-// Otherwise, use ARG_ENABLE
-// ARG_ENABLE("$extname", "enable $extname support", "no");
-
-if (PHP_$EXTNAME != "no") {
- EXTENSION("$extname", "$extname.c", PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
-}
-
-eof
-
-$ECHO_N " .gitignore$ECHO_C"
-cat >.gitignore <<eof
-.deps
-*.lo
-*.la
-.libs
-acinclude.m4
-aclocal.m4
-autom4te.cache
-build
-config.guess
-config.h
-config.h.in
-config.log
-config.nice
-config.status
-config.sub
-configure
-configure.ac
-include
-install-sh
-libtool
-ltmain.sh
-Makefile
-Makefile.fragments
-Makefile.global
-Makefile.objects
-missing
-mkinstalldirs
-modules
-run-tests.php
-tests/*/*.diff
-tests/*/*.out
-tests/*/*.php
-tests/*/*.exp
-tests/*/*.log
-tests/*/*.sh
-eof
-
-$ECHO_N " $extname.c$ECHO_C"
-echo "s/extname/$extname/g" > sedscript
-echo "s/EXTNAME/$EXTNAME/g" >> sedscript
-echo '/__function_entries_here__/r function_entries' >> sedscript
-echo '/__function_stubs_here__/r function_stubs' >> sedscript
-echo '/__header_here__/r ../../header' >> sedscript
-echo '/__footer_here__/r ../../footer' >> sedscript
-echo '/__function_entries_here__/D' >> sedscript
-echo '/__function_stubs_here__/D' >> sedscript
-echo '/__header_here__/D' >> sedscript
-echo '/__footer_here__/D' >> sedscript
-if [ ! -z "$no_help" ]; then
- echo "/confirm_$extname_compiled/D" >> sedscript
- echo '/Remove the following/,/^\*\//D' >> sedscript
- echo 's/[[:space:]]\/\*.\+\*\///' >> sedscript
- echo 's/^\/\*.*\*\/$//' >> sedscript
- echo '/^[[:space:]]*\/\*/,/^[[:space:]]*\*\//D' >> sedscript
-fi
-
-sed -f sedscript < $skel_dir/skeleton.c > $extname.c
-
-
-$ECHO_N " php_$extname.h$ECHO_C"
-echo "s/extname/$extname/g" > sedscript
-echo "s/EXTNAME/$EXTNAME/g" >> sedscript
-echo '/__function_declarations_here__/r function_declarations' >> sedscript
-echo '/__header_here__/r ../../header' >> sedscript
-echo '/__footer_here__/r ../../footer' >> sedscript
-echo '/__function_declarations_here__/D' >> sedscript
-echo '/__header_here__/D' >> sedscript
-echo '/__footer_here__/D' >> sedscript
-if [ ! -z "$no_help" ]; then
- echo "/confirm_$extname_compiled/D" >> sedscript
- echo 's/[[:space:]]\/\*.\+\*\///' >> sedscript
- echo 's/^\/\*.*\*\/$//' >> sedscript
- echo '/^[[:space:]]*\/\*/,/^[[:space:]]*\*\//D' >> sedscript
-fi
-sed -f sedscript <$skel_dir/php_skeleton.h > php_$extname.h
-
-$ECHO_N " CREDITS$ECHO_C"
-echo "s/extname/$extname/g" > sedscript
-sed -f sedscript <$skel_dir/CREDITS > CREDITS
-
-$ECHO_N " EXPERIMENTAL$ECHO_C"
-echo "s/extname/$extname/g" > sedscript
-sed -f sedscript <$skel_dir/EXPERIMENTAL > EXPERIMENTAL
-
-$ECHO_N " tests/001.phpt$ECHO_C"
-mkdir tests || givup "Cannot create tests directory"
-chmod 755 tests
-sed -f sedscript <$skel_dir/tests/001.phpt > tests/001.phpt
-
-if test -z "$stubs" && test -z "$no_help"; then
- $ECHO_N " $extname.php$ECHO_C"
- sed \
- -e "s/extname/$extname/g" \
- <$skel_dir/skeleton.php \
- > $extname.php
-fi
-
-rm sedscript
-
-if test -n "$proto"; then
- if test -z "$stubs"; then
- rm function_entries
- rm function_declarations
- rm function_stubs
- fi
- if test -f function_warning; then
- rm function_warning
- warning="
-NOTE! Because some arguments to functions were resources, the code generated
-cannot yet be compiled without editing. Please consider this to be step 4.5
-in the instructions above.
-"
- fi
-fi
-
-find . -type f | xargs chmod 644
-find . -type d | xargs chmod 755
-fi
-
-echo " [done]."
-
-if test -z "$no_help" && test -z "$stubs"; then
- cat <<eof
-
-To use your new extension, you will have to execute the following steps:
-
-1. $ cd ..
-2. $ vi ext/$extname/config.m4
-3. $ ./buildconf
-4. $ ./configure --[with|enable]-$extname
-5. $ make
-6. $ ./sapi/cli/php -f ext/$extname/$extname.php
-7. $ vi ext/$extname/$extname.c
-8. $ make
-
-Repeat steps 3-6 until you are satisfied with ext/$extname/config.m4 and
-step 6 confirms that your module is compiled into PHP. Then, start writing
-code and repeat the last two steps as often as necessary.
-$warning
-eof
-fi
--- /dev/null
+<?php
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2017 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Kalle Sommer Nielsen <kalle@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+/* {{{ error
+ */
+function error($message) {
+ printf('Error: %s%s', $message, PHP_EOL);
+ exit;
+}
+/* }}} */
+
+/* {{{ print_help
+ */
+function print_help() {
+ printf('php ext_skel.php --ext=<name> [--experimental] [--author=<name>]%s', PHP_EOL);
+ printf(' [--dir=<path>] [--std] [--onlyunix]%s', PHP_EOL);
+ printf(' [--onlywindows] [--help]%1$s%1$s', PHP_EOL);
+ printf(' --ext=<name> The name of the extension defined as <name>%s', PHP_EOL);
+ printf(' --experimental Passed if this extension is experimental, this creates%s', PHP_EOL);
+ printf(' the EXPERIMENTAL file in the root of the extension%s', PHP_EOL);
+ printf(' --author=<name> Your name, this is used if --header is passed and%s', PHP_EOL);
+ printf(' for the CREDITS file%s', PHP_EOL);
+ printf(' --dir=<path> Path to the directory for where extension should be%s', PHP_EOL);
+ printf(' created. Defaults to the directory of where this script%s', PHP_EOL);
+ printf(' lives%s', PHP_EOL);
+ printf(' --std If passed, the standard header and vim rules footer used%s', PHP_EOL);
+ printf(' in extensions that is included in the core, will be used%s', PHP_EOL);
+ printf(' --onlyunix Only generate configure scripts for Unix%s', PHP_EOL);
+ printf(' --onlywindows Only generate configure scripts for Windows%s', PHP_EOL);
+ printf(' --help This help%s', PHP_EOL);
+
+ exit;
+}
+/* }}} */
+
+/* {{{ task
+ */
+function task($label, $callback) {
+ printf('%s... ', $label);
+
+ $callback();
+
+ printf('done%s', PHP_EOL);
+}
+/* }}} */
+
+/* {{{ print_success
+ */
+function print_success() {
+ global $options;
+
+ if (PHP_OS_FAMILY != 'Windows') {
+ $file_prefix = './';
+ $make_prefix = '';
+ } else {
+ $file_prefix = '';
+ $make_prefix = 'n';
+ }
+
+ printf('%1$sSuccess. The extension is now ready to be compiled into PHP. To do so, use the%s', PHP_EOL);
+ printf('following steps:%1$s%1$s', PHP_EOL);
+ printf('cd /path/to/php-src%s', PHP_EOL);
+ printf('%sbuildconf%s', $file_prefix, PHP_EOL);
+ printf('%sconfigure --enable-%s%s', $file_prefix, $options['ext'], PHP_EOL);
+ printf('%smake%2$s%2$s', $make_prefix, PHP_EOL);
+ printf('Don\'t forget to run tests once the compilation is done:%s', PHP_EOL);
+ printf('%smake test TESTS=ext/%s/tests%3$s%3$s', $make_prefix, $options['ext'], PHP_EOL);
+ printf('Thank you for using PHP!%s', PHP_EOL);
+}
+/* }}} */
+
+/* {{{ process_args
+ */
+function process_args($argv, $argc) {
+ $options = [
+ 'unix' => true,
+ 'windows' => true,
+ 'ext' => '',
+ 'dir' => __DIR__ . DIRECTORY_SEPARATOR,
+ 'skel' => __DIR__ . DIRECTORY_SEPARATOR . 'skeleton' . DIRECTORY_SEPARATOR,
+ 'author' => false,
+ 'experimental' => false,
+ 'std' => false
+ ];
+
+ for($i = 1; $i < $argc; ++$i)
+ {
+ $val = $argv[$i];
+
+ if($val{0} != '-' || $val{1} != '-')
+ {
+ continue;
+ }
+
+ switch($opt = strtolower(substr($val, 2)))
+ {
+ case 'help': {
+ print_help();
+ }
+ case 'onlyunix': {
+ $options['windows'] = false;
+ }
+ break;
+ case 'onlywindows': {
+ $options['unix'] = false;
+ }
+ break;
+ case 'experimental': {
+ $options['experimental'] = true;
+ }
+ break;
+ case 'std': {
+ $options['std'] = true;
+ }
+ break;
+ case 'ext':
+ case 'dir':
+ case 'author': {
+ if (!isset($argv[$i + 1]) || ($argv[$i + 1]{0} == '-' && $argv[$i + 1]{1} == '-')) {
+ error('Argument "' . $val . '" expects a value, none passed');
+ } else if ($opt == 'dir' && empty($argv[$i + 1])) {
+ continue;
+ }
+
+ $options[$opt] = ($opt == 'dir' ? realpath($argv[$i + 1]) : $argv[$i + 1]);
+ }
+ break;
+ default: {
+ error('Unsupported argument "' . $val . '" passed');
+ }
+ }
+ }
+
+ if (empty($options['ext'])) {
+ error('No extension name passed, use "--ext <name>"');
+ } else if (!$options['unix'] && !$options['windows']) {
+ error('Cannot pass both --onlyunix and --onlywindows');
+ } else if (!is_dir($options['skel'])) {
+ error('The skeleton directory was not found');
+ }
+
+ $options['ext'] = str_replace(['\\', '/'], '', strtolower($options['ext']));
+
+ return $options;
+}
+/* }}} */
+
+/* {{{ process_source_tags
+ */
+function process_source_tags($file, $short_name) {
+ global $options;
+
+ $source = file_get_contents($file);
+
+ if ($source === false) {
+ error('Unable to open file for reading: ' . $short_name);
+ }
+
+ $source = str_replace('%EXTNAME%', $options['ext'], $source);
+ $source = str_replace('%EXTNAMECAPS%', strtoupper($options['ext']), $source);
+
+ if (strpos($short_name, '.c') !== false || strpos($short_name, '.h') !== false) {
+ static $header, $footer;
+
+ if (!$header) {
+ if ($options['std']) {
+ $year = date('Y');
+ $author_len = strlen($options['author']);
+ $credits = $options['author'] . ($author_len && $author_len <= 60 ? str_repeat(' ', 60 - $author_len) : '');
+
+ $header = <<<"HEADER"
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-$year The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: $credits |
+ +----------------------------------------------------------------------+
+*/
+HEADER;
+ $footer = <<<'FOOTER'
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+FOOTER;
+ } else {
+ if ($options['author']) {
+ $header = sprintf('/* %s extension for PHP (c) %d %s */', $options['ext'], date('Y'), $options['author']);
+ } else {
+ $header = sprintf('/* %s extension for PHP */', $options['ext']);
+ }
+
+ $footer = '';
+ }
+ }
+
+ $source = str_replace(['%HEADER%', '%FOOTER%'], [$header, $footer], $source);
+ }
+
+ if (!file_put_contents($file, $source)) {
+ error('Unable to save contents to file: ' . $short_name);
+ }
+}
+/* }}} */
+
+/* {{{ copy_config_scripts
+ */
+function copy_config_scripts() {
+ global $options;
+
+ $files = [];
+
+ if ($options['unix']) {
+ $files[] = 'config.m4';
+ }
+
+ if ($options['windows']) {
+ $files[] = 'config.w32';
+ }
+
+ if (!$files) {
+ return;
+ }
+
+ foreach($files as $config_script) {
+ $new_config_script = $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $config_script;
+
+ if (!copy($options['skel'] . $config_script . '.in', $new_config_script)) {
+ error('Unable to copy config script: ' . $config_script);
+ }
+
+ process_source_tags($new_config_script, $config_script);
+ }
+}
+/* }}} */
+
+/* {{{ copy_sources
+ */
+function copy_sources() {
+ global $options;
+
+ $files = [
+ 'skeleton.c' => $options['ext'] . '.c',
+ 'php_skeleton.h' => 'php_' . $options['ext'] . '.h'
+ ];
+
+ foreach ($files as $src_file => $dst_file) {
+ if (!copy($options['skel'] . $src_file, $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $dst_file)) {
+ error('Unable to copy source file: ' . $src_file);
+ }
+
+ process_source_tags($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $dst_file, $dst_file);
+ }
+}
+/* }}} */
+
+/* {{{ copy_tests
+ */
+function copy_tests() {
+ global $options;
+
+ $test_files = glob($options['skel'] . 'tests/*', GLOB_MARK);
+
+ if (!$test_files) {
+ return;
+ }
+
+ foreach ($test_files as $test) {
+ if (is_dir($test)) {
+ continue;
+ }
+
+ $new_test = str_replace([$options['skel'], '/'], ['', DIRECTORY_SEPARATOR], $test);
+
+ if (!copy($test, $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $new_test)) {
+ error('Unable to copy file: ' . $new_test);
+ }
+
+ process_source_tags($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $new_test, $new_test);
+ }
+}
+/* }}} */
+
+
+if (PHP_SAPI != 'cli') {
+ error('This script is only suited for CLI');
+}
+
+if ($argc < 1) {
+ print_help();
+ exit;
+}
+
+$options = process_args($argv, $argc);
+
+if (!$options['dir'] || !is_dir($options['dir'])) {
+ error('The selected output directory does not exists');
+} else if (is_dir($options['dir'] . $options['ext'])) {
+ error('There is already a folder named "' . $options['ext'] . '" in the output directory');
+} else if (!mkdir($options['dir'] . $options['ext'])) {
+ error('Unable to create extension directory in the output directory');
+} else if (!mkdir($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'tests')) {
+ error('Unable to create the tests directory');
+}
+
+if ($options['experimental']) {
+ print('Creating EXPERIMENTAL... ');
+
+ if (file_put_contents($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'EXPERIMENTAL', '') === false) {
+ error('Unable to create the EXPERIMENTAL file');
+ }
+
+ printf('done%s', PHP_EOL);
+}
+
+if (!empty($options['author'])) {
+ print('Creating CREDITS... ');
+
+ if (!file_put_contents($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'CREDITS', $options['ext'] . PHP_EOL . $options['author'])) {
+ error('Unable to create the CREDITS file');
+ }
+
+ printf('done%s', PHP_EOL);
+}
+
+date_default_timezone_set('UTC');
+
+task('Copying config scripts', 'copy_config_scripts');
+task('Copying sources', 'copy_sources');
+task('Copying tests', 'copy_tests');
+
+print_success();
+
+?>
\ No newline at end of file
+++ /dev/null
-<?php
-/* $Id$ */
-
-if (php_sapi_name() != "cli") {
- echo "Please run this script using the CLI version of PHP\n";
- exit;
-}
-/*
- This script can be used on Win32 systems
-
- 1) Make sure you have CygWin installed
- 2) Adjust the $cygwin_path to match your installation
- 3) Change the environment cariable PATHEXT to include .PHP
- 4) run ext_skel --extname=...
- the first time you run this script you will be asked to
- associate it with a program. chooses the CLI version of php.
-*/
-
-$cygwin_path = 'c:\cygwin\bin';
-
-$path = getenv("PATH");
-putenv("PATH=$cygwin_path;$path");
-
-array_shift($argv);
-system("sh ext_skel " . implode(" ", $argv));
-
-$extname = "";
-$skel = "skeleton";
-foreach($argv as $arg) {
- if (strtolower(substr($arg, 0, 9)) == "--extname") {
- $extname = substr($arg, 10);
- }
- if (strtolower(substr($arg, 0, 6)) == "--skel") {
- $skel = substr($arg, 7);
- }
-}
-
-$fp = fopen("$extname/$extname.php", "rb");
-if ($fp) {
- $php_file = fread($fp, filesize("$extname/$extname.php"));
- fclose($fp);
-
- $php_file = str_replace("dl('", "dl('php_", $php_file);
- $fp = fopen("$extname/$extname.php", "wb");
- if ($fp) {
- fwrite($fp, $php_file);
- fclose($fp);
- }
-}
-
-?>
-
+++ /dev/null
-extname
\ No newline at end of file
+++ /dev/null
-#!/usr/bin/awk -f
-
-function gobble(s, x)
-{
- sub(/^ /, "", line)
- match(line, "^" "(" s ")")
- x = substr(line, 1, RLENGTH)
- line = substr(line, RLENGTH+1)
- return x
-}
-
-function convert(i, j, t)
-{
- type = argtypes[i,j]
- name = argnames[i,j]
- opt = optionals[i,j]
- tabs = x = ""
-
- for (i = 0; i < t; i++) { tabs = tabs "\t" }
-
- if (type == "int" || type == "long") {
- longs = longs "\tzend_long " name ";\n"
- } else if (type == "bool" || type == "boolean") {
- bools = bools "\tzend_bool " name ";\n"
- } else if (type == "double" || type == "float") {
- doubles = doubles "\tdouble " name ";\n"
- } else if (type == "string") {
- strings = strings "\tchar *" name " = NULL;\n"
- ints = ints "\tsize_t " name "_len;\n"
- } else if (type == "array" || type == "object" || type == "mixed") {
- zvals = zvals "\tzval *" name " = NULL;\n"
- } else if (type == "resource" || type == "handle") {
- zvals = zvals "\tzval *" name " = NULL;\n"
- resources = resources "\tif (" name ") {\n" \
- "\t\tZEND_FETCH_RESOURCE(???, ???, " name ", " name "_id, \"???\", ???_rsrc_id);\n\t}\n"
- ints = ints "\tint " name "_id = -1;\n"
- }
-}
-
-function comment(s)
-{
- if (i_know_what_to_do_shut_up_i_dont_need_your_help_mode) {
- return
- } else {
- return s
- }
-}
-
-BEGIN {
- name = "[_A-Za-z][_A-Za-z0-9]*"
- type = "int|long|double|float|string|bool|boolean|array|object|resource|handle|mixed|void"
- spec = "l|l|d|d|s|b|b|a|o|r|r|z|"
- num_funcs = 0
-
-# create a map from type name to the spec
- split(type, type_array, "\|")
- split(spec, spec_array, "\|")
- for (i in type_array) {
- spec_map[type_array[i]] = spec_array[i]
- }
-
- if (xml && xml != "yes") {
- xmldoc = xml
- } else {
- xmldoc = extname "/" extname ".xml"
- }
-
-
- xmlhead = "<?xml version='1.0' encoding='iso-8859-1'?>\n" \
- "<!-- $Id$ -->\n" \
- " <reference id=\"ref." extname "\">\n" \
- " <title> functions</title>\n" \
- " <titleabbrev></titleabbrev>\n\n" \
- " <partintro>\n" \
- " &warn.experimental;\n" \
- " <para>\n" \
- " </para>\n" \
- " </partintro>\n\n";
-
- xmlfoot = " </reference>\n\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"
-}
-
-{
- args_max = args_min = optional = i = spec_opt = 0
- line = $0
- spec_str = "\""
-
-## php extension must use lower case function names.
-## this will translate any capitalized letter to lowercase
-## and warn the user
- if (match(func_name,"[A-Z]") != 0) {
- printf("NOTICE: lower casing function name '%s'\n",func_name)
- func_name = tolower(func_name)
- }
- func_type = gobble(type);
- func_name = gobble(name);
-
- if (gobble("\\(")) {
- if (gobble("\\[")) optional = 1
- while (arg_type = gobble(type)) {
- arg_name = gobble(name)
- if(arg_type == "void") {
- args_max = 0;
- args_min = 0;
- break;
- } else {
- argtypes[num_funcs,args_max] = arg_type
- argnames[num_funcs,args_max] = arg_name
-
- args_max++
- if (optional) {
- if (!spec_opt) {
- spec_str = spec_str "|"
- spec_opt = 1
- }
- optionals[num_funcs,i] = optional
- } else {
- args_min++
- }
- spec_str = spec_str spec_map[arg_type]
-
- if (x = gobble("\\[")) {
- optional++
- }
-
- y = gobble(",")
- if (!x && y && optional) {
- grouped_optional_param[num_funcs,i] = 1
- }
- i++
- }
- }
- }
-
-# if (x = gobble("\\)")) {
- gobble("\\]* *\\)")
- sub(/^[ \t]+/, "", line)
- fcomments[num_funcs] = line
-# }
-
- spec_str = spec_str "\""
-
- funcs[num_funcs] = func_name
- types[num_funcs] = func_type
- maxargs[num_funcs] = args_max
- minargs[num_funcs] = args_min
- specs[num_funcs] = spec_str
- spec_opts[num_funcs] = spec_opt
-
- num_funcs++
-}
-
-END {
- if (xml) print xmlhead > xmldoc
- for (i = 0; i < num_funcs; i++) {
- compareargc = maxargs[i] - minargs[i]
- closefetch = fetchargs = zvals = xmlparams = funcvals = resources = handleargs = closeopts = ""
- ints = longs = doubles = strings = bools = zvals = ""
-
- proto = "/* {{{ proto " types[i] " " funcs[i] "("
-
- refid = funcs[i]
- gsub(/_/, "-", refid)
- xmlstr = " <refentry id=\"function." refid "\">\n" \
- " <refnamediv>\n" \
- " <refname>" funcs[i] "</refname>\n" \
- " <refpurpose>" fcomments[i] "</refpurpose>\n" \
- " </refnamediv>\n" \
- " <refsect1>\n" \
- " <title>Description</title>\n" \
- " <funcsynopsis>\n" \
- " <funcprototype>\n" \
- " <funcdef>" types[i] " <function>" funcs[i] "</function></funcdef>\n"
-
- if (maxargs[i]>0) {
- fetchargs = "\tif (zend_parse_parameters("
- ints = ints "\tint argc = ZEND_NUM_ARGS();\n"
- fetchargs = fetchargs "argc, " specs[i]
- } else {
- fetchargs = fetchargs "\tif (zend_parse_parameters_none() == FAILURE) {\n\t\treturn;\n\t}"
- xmlparams = xmlparams " <void/>\n"
- }
-
- for (j = 0; j < maxargs[i]; j++) {
-
- fetchargs = fetchargs ", "
-
- fetchargs = fetchargs "&" argnames[i,j]
- if (argtypes[i,j] == "string") {
- fetchargs = fetchargs ", &" argnames[i,j] "_len"
- }
-
- xmlparams = xmlparams " <paramdef>" argtypes[i,j]
- if (j > minargs[i]-1) {
- if (!grouped_optional_param[i,j-1]) {
- if (j > 0) proto = proto " "
- proto = proto "["
- closeopts = closeopts "]"
- }
- xmlparams = xmlparams "\n <parameter><optional>" \
- argnames[i,j] \
- "</optional></parameter>\n </paramdef>\n"
- } else {
- xmlparams = xmlparams \
- " <parameter>" \
- argnames[i,j] \
- "</parameter></paramdef>\n"
- }
-
- if (j > 0) proto = proto ", "
- proto = proto argtypes[i,j] " " argnames[i,j]
-
- convert(i, j, 1)
- }
-
- proto = proto closeopts ")\n " fcomments[i] " */\nPHP_FUNCTION(" funcs[i] ")\n{"
- if (maxargs[i]>0) {
- fetchargs = fetchargs ") == FAILURE)" closefetch " \n\t\treturn;\n"
- }
- funcvals = strings ints longs doubles bools zvals
- xmlstr = xmlstr xmlparams \
- " </funcprototype>\n" \
- " </funcsynopsis>\n" \
- " &warn.experimental.func;\n" \
- " <para>\n" \
- " &warn.undocumented.func;\n" \
- " </para>\n" \
- " </refsect1>\n" \
- " </refentry>\n"
-
- print proto > stubfile
- if (funcvals) print funcvals > stubfile
- if (fetchargs) print fetchargs > stubfile
- if (resources) {
- print resources > stubfile
- if (!stubs) print "" > ( extname "/function_warning" )
- }
- if (!i_know_what_to_do_shut_up_i_dont_need_your_help_mode) {
- print "\tphp_error(E_WARNING, \"" funcs[i] ": not yet implemented\");" > stubfile
- }
- print "}\n/* }}} */\n" > stubfile
-
- if (stubs) {
- h_stubs = h_stubs "PHP_FUNCTION(" funcs[i] ");\n"
- c_stubs = c_stubs "\tPHP_FE(" funcs[i] ",\tNULL)\n"
- } else {
- print "PHP_FUNCTION(" funcs[i] ");" > ( extname "/function_declarations" )
- print "\tPHP_FE(" funcs[i] ",\tNULL)" > ( extname "/function_entries" )
- }
-
- if (xml) print xmlstr > xmldoc
- }
-
- if (stubs) {
- print "\n/* ----------------------------------------------------------- */\n" > stubfile
- print c_stubs > stubfile
- print "\n/* ----------------------------------------------------------- */\n" > stubfile
- print h_stubs > stubfile
- }
-
- if (xml) print xmlfoot > xmldoc
-}
-
-#
-# Local variables:
-# tab-width: 2
-# c-basic-offset: 2
-# End:
-
-/* __header_here__ */
+%HEADER%
-#ifndef PHP_EXTNAME_H
-#define PHP_EXTNAME_H
+#ifndef PHP_%EXTNAMECAPS%_H
+# define PHP_%EXTNAMECAPS%_H
-extern zend_module_entry extname_module_entry;
-#define phpext_extname_ptr &extname_module_entry
+extern zend_module_entry %EXTNAME%_module_entry;
+# define phpext_%EXTNAME%_ptr &%EXTNAME%_module_entry
-#define PHP_EXTNAME_VERSION "0.1.0" /* Replace with version number for your extension */
+# define PHP_%EXTNAMECAPS%_VERSION "0.1.0"
-#ifdef PHP_WIN32
-# define PHP_EXTNAME_API __declspec(dllexport)
-#elif defined(__GNUC__) && __GNUC__ >= 4
-# define PHP_EXTNAME_API __attribute__ ((visibility("default")))
-#else
-# define PHP_EXTNAME_API
-#endif
-
-#ifdef ZTS
-#include "TSRM.h"
-#endif
-
-/*
- Declare any global variables you may need between the BEGIN
- and END macros here:
-
-ZEND_BEGIN_MODULE_GLOBALS(extname)
- zend_long global_value;
- char *global_string;
-ZEND_END_MODULE_GLOBALS(extname)
-*/
-
-/* Always refer to the globals in your function as EXTNAME_G(variable).
- You are encouraged to rename these macros something shorter, see
- examples in any other php module directory.
-*/
-#define EXTNAME_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(extname, v)
-
-#if defined(ZTS) && defined(COMPILE_DL_EXTNAME)
+# if defined(ZTS) && defined(COMPILE_DL_%EXTNAMECAPS%)
ZEND_TSRMLS_CACHE_EXTERN()
-#endif
-
-#endif /* PHP_EXTNAME_H */
+# endif
-/* __footer_here__ */
+#endif /* PHP_%EXTNAMECAPS%_H */
+%FOOTER%
\ No newline at end of file
-/* __header_here__ */
+%HEADER%
#ifdef HAVE_CONFIG_H
-#include "config.h"
+# include "config.h"
#endif
#include "php.h"
-#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_extname.h"
+#include "php_%EXTNAME%.h"
-/* If you declare any globals in php_extname.h uncomment this:
-ZEND_DECLARE_MODULE_GLOBALS(extname)
-*/
-
-/* True global resources - no need for thread safety here */
-static int le_extname;
-
-/* {{{ PHP_INI
+/* {{{ void %EXTNAME%_test1()
*/
-/* Remove comments and fill if you need to have entries in php.ini
-PHP_INI_BEGIN()
- STD_PHP_INI_ENTRY("extname.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_extname_globals, extname_globals)
- STD_PHP_INI_ENTRY("extname.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_extname_globals, extname_globals)
-PHP_INI_END()
-*/
-/* }}} */
-
-/* Remove the following function when you have successfully modified config.m4
- so that your module can be compiled into PHP, it exists only for testing
- purposes. */
-
-/* Every user-visible function in PHP should document itself in the source */
-/* {{{ proto string confirm_extname_compiled(string arg)
- Return a string to confirm that the module is compiled in */
-PHP_FUNCTION(confirm_extname_compiled)
+PHP_FUNCTION(%EXTNAME%_test1)
{
- char *arg = NULL;
- size_t arg_len, len;
- zend_string *strg;
+ ZEND_PARSE_PARAMETERS_NONE();
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
- return;
- }
-
- strg = strpprintf(0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "extname", arg);
-
- RETURN_STR(strg);
+ php_printf("The extension %s is loaded and working!\r\n", "%EXTNAME%");
}
/* }}} */
-/* The previous line is meant for vim and emacs, so it can correctly fold and
- unfold functions in source code. See the corresponding marks just before
- function definition, where the functions purpose is also documented. Please
- follow this convention for the convenience of others editing your code.
-*/
-/* __function_stubs_here__ */
-
-/* {{{ php_extname_init_globals
+/* {{{ string %EXTNAME%_test2( [ string $var ] )
*/
-/* Uncomment this function if you have INI entries
-static void php_extname_init_globals(zend_extname_globals *extname_globals)
+PHP_FUNCTION(%EXTNAME%_test2)
{
- extname_globals->global_value = 0;
- extname_globals->global_string = NULL;
-}
-*/
-/* }}} */
+ char *var = "World";
+ size_t var_len = sizeof("World") - 1;
+ zend_string *retval;
-/* {{{ PHP_MINIT_FUNCTION
- */
-PHP_MINIT_FUNCTION(extname)
-{
- /* If you have INI entries, uncomment these lines
- REGISTER_INI_ENTRIES();
- */
- return SUCCESS;
-}
-/* }}} */
+ ZEND_PARSE_PARAMETERS_START(0, 1)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_STRING(var, var_len)
+ ZEND_PARSE_PARAMETERS_END();
-/* {{{ PHP_MSHUTDOWN_FUNCTION
- */
-PHP_MSHUTDOWN_FUNCTION(extname)
-{
- /* uncomment this line if you have INI entries
- UNREGISTER_INI_ENTRIES();
- */
- return SUCCESS;
+ retval = strpprintf(0, "Hello %s", var);
+
+ RETURN_STR(retval);
}
-/* }}} */
+/* }}}*/
-/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
-PHP_RINIT_FUNCTION(extname)
+PHP_RINIT_FUNCTION(%EXTNAME%)
{
-#if defined(COMPILE_DL_EXTNAME) && defined(ZTS)
+#if defined(ZTS) && defined(COMPILE_DL_%EXTNAMECAPS%)
ZEND_TSRMLS_CACHE_UPDATE();
#endif
- return SUCCESS;
-}
-/* }}} */
-/* Remove if there's nothing to do at request end */
-/* {{{ PHP_RSHUTDOWN_FUNCTION
- */
-PHP_RSHUTDOWN_FUNCTION(extname)
-{
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
-PHP_MINFO_FUNCTION(extname)
+PHP_MINFO_FUNCTION(%EXTNAME%)
{
php_info_print_table_start();
- php_info_print_table_header(2, "extname support", "enabled");
+ php_info_print_table_header(2, "%EXTNAME% support", "enabled");
php_info_print_table_end();
-
- /* Remove comments if you have entries in php.ini
- DISPLAY_INI_ENTRIES();
- */
}
/* }}} */
-/* {{{ extname_functions[]
- *
- * Every user visible function must have an entry in extname_functions[].
+/* {{{ arginfo
+ */
+ZEND_BEGIN_ARG_INFO(arginfo_%EXTNAME%_test1, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_%EXTNAME%_test2, 0)
+ ZEND_ARG_INFO(0, str)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+/* {{{ %EXTNAME%_functions[]
*/
-const zend_function_entry extname_functions[] = {
- PHP_FE(confirm_extname_compiled, NULL) /* For testing, remove later. */
- /* __function_entries_here__ */
- PHP_FE_END /* Must be the last line in extname_functions[] */
+const zend_function_entry %EXTNAME%_functions[] = {
+ PHP_FE(%EXTNAME%_test1, arginfo_%EXTNAME%_test1)
+ PHP_FE(%EXTNAME%_test2, arginfo_%EXTNAME%_test2)
+ PHP_FE_END
};
/* }}} */
-/* {{{ extname_module_entry
+/* {{{ %EXTNAME%_module_entry
*/
-zend_module_entry extname_module_entry = {
+zend_module_entry %EXTNAME%_module_entry = {
STANDARD_MODULE_HEADER,
- "extname",
- extname_functions,
- PHP_MINIT(extname),
- PHP_MSHUTDOWN(extname),
- PHP_RINIT(extname), /* Replace with NULL if there's nothing to do at request start */
- PHP_RSHUTDOWN(extname), /* Replace with NULL if there's nothing to do at request end */
- PHP_MINFO(extname),
- PHP_EXTNAME_VERSION,
+ "%EXTNAME%", /* Extension name */
+ %EXTNAME%_functions, /* zend_function_entry */
+ NULL, /* PHP_MINIT - Module initialization */
+ NULL, /* PHP_MSHUTDOWN - Module shutdown */
+ PHP_RINIT(%EXTNAME%), /* PHP_RINIT - Request initialization */
+ NULL, /* PHP_RSHUTDOWN - Request shutdown */
+ PHP_MINFO(%EXTNAME%), /* PHP_MINFO - Module info */
+ PHP_%EXTNAMECAPS%_VERSION, /* Version */
STANDARD_MODULE_PROPERTIES
};
/* }}} */
-#ifdef COMPILE_DL_EXTNAME
-#ifdef ZTS
+#ifdef COMPILE_DL_%EXTNAMECAPS%
+# ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
+# endif
+ZEND_GET_MODULE(%EXTNAME%)
#endif
-ZEND_GET_MODULE(extname)
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
+%FOOTER%
\ No newline at end of file
+++ /dev/null
-<?php
-$br = (php_sapi_name() == "cli")? "":"<br>";
-
-if(!extension_loaded('extname')) {
- dl('extname.' . PHP_SHLIB_SUFFIX);
-}
-$module = 'extname';
-$functions = get_extension_funcs($module);
-echo "Functions available in the test extension:$br\n";
-foreach($functions as $func) {
- echo $func."$br\n";
-}
-echo "$br\n";
-$function = 'confirm_' . $module . '_compiled';
-if (extension_loaded($module)) {
- $str = $function($module);
-} else {
- $str = "Module $module is not compiled into PHP";
-}
-echo "$str\n";
-?>
--TEST--
-Check for extname presence
+Check if %EXTNAME% is loaded
--SKIPIF--
-<?php if (!extension_loaded("extname")) print "skip"; ?>
+<?php
+if (!extension_loaded('%EXTNAME%')) {
+ echo 'skip';
+}
+?>
--FILE--
<?php
-echo "extname extension is available";
-/*
- you can add regression tests for your extension here
-
- the output of your test code has to be equal to the
- text in the --EXPECT-- section below for the tests
- to pass, differences between the output and the
- expected text are interpreted as failure
-
- see php7/README.TESTING for further information on
- writing regression tests
-*/
+echo 'The extension "%EXTNAME%" is available';
?>
--EXPECT--
-extname extension is available
+The extension "%EXTNAME%" is available
--- /dev/null
+--TEST--
+%EXTNAME%_test1() Basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('%EXTNAME%')) {
+ echo 'skip';
+}
+?>
+--FILE--
+<?php
+$ret = %EXTNAME%_test1();
+
+var_dump($ret);
+?>
+--EXPECT--
+The extension %EXTNAME% is loaded and working!
+NULL
--- /dev/null
+--TEST--
+%EXTNAME%_test2() Basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('%EXTNAME%')) {
+ echo 'skip';
+}
+?>
+--FILE--
+<?php
+var_dump(%EXTNAME%_test2());
+var_dump(%EXTNAME%_test2('PHP'));
+?>
+--EXPECT--
+string(11) "Hello World"
+string(9) "Hello PHP"