');
if ($this->language == "cpp") {
fputs($fp, "}\n");
}
if (isset($this->headers)) {
foreach ($this->headers as $header) {
if (@$header["prepend"] !== "yes") {
fputs($fp, "#include <$header[name]>\n");
}
}
}
if (isset($this->code["header"])) {
foreach ($this->code["header"] as $code) {
fputs($fp, $code);
}
}
fputs($fp, "
extern zend_module_entry {$this->name}_module_entry;
#define phpext_{$this->name}_ptr &{$this->name}_module_entry
#ifdef PHP_WIN32
#define PHP_{$upname}_API __declspec(dllexport)
#else
#define PHP_{$upname}_API
#endif
PHP_MINIT_FUNCTION({$this->name});
PHP_MSHUTDOWN_FUNCTION({$this->name});
PHP_RINIT_FUNCTION({$this->name});
PHP_RSHUTDOWN_FUNCTION({$this->name});
PHP_MINFO_FUNCTION({$this->name});
#ifdef ZTS
#include \"TSRM.h\"
#endif
");
fputs($fp, $this->generate_globals_h());
fputs($fp, "\n");
foreach ($this->functions as $name => $function) {
fputs($fp, "PHP_FUNCTION($name);\n");
}
fputs($fp, "\n");
fputs($fp, "#endif /* PHP_HAVE_{$upname} */\n\n");
fputs($fp, "#endif /* PHP_{$upname}_H */\n\n");
fputs($fp, $this->editor_config_c());
fclose($fp);
}
// }}}
// {{{ internal functions
function internal_functions_c() {
$need_block = false;
$code = "
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION({$this->name})
{
";
if (count($this->globals)) {
$code .= "\tZEND_INIT_MODULE_GLOBALS({$this->name}, php_{$this->name}_init_globals, NULL)\n";
$need_block = true;
}
if (count($this->phpini)) {
$code .= "\tREGISTER_INI_ENTRIES();\n";
$need_block = true;
}
if (isset($this->logo)) {
$code .= $this->logo->minit_code();
$need_block = true;
}
if (count($this->constants)) {
foreach ($this->constants as $constant) {
$code .= $constant->c_code();
}
$need_block = true;
}
if (count($this->resources)) {
foreach ($this->resources as $resource) {
$code .= $resource->minit_code();
}
$need_block = true;
}
if (isset($this->internal_functions['MINIT'])) {
if ($need_block) $code .= "\n\t{\n";
$code .= $this->internal_functions['MINIT']->code;
if ($need_block) $code .= "\n\t}\n";
} else {
$code .="\n\t/* add your stuff here */\n";
}
$code .= "
return SUCCESS;
}
/* }}} */
";
$code .= "
/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION({$this->name})
{
";
if (count($this->phpini)) {
$code .= "\tUNREGISTER_INI_ENTRIES();\n";
}
if (isset($this->internal_functions['MSHUTDOWN'])) {
if (count($this->phpini)) $code .= "\n\t{\n";
$code .= $this->internal_functions['MSHUTDOWN']->code;
if (count($this->phpini)) $code .= "\n\t}\n";
} else {
$code .="\n\t/* add your stuff here */\n";
}
$code .= "
return SUCCESS;
}
/* }}} */
";
$code .= "
/* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION({$this->name})
{
";
if (isset($this->internal_functions['RINIT'])) {
$code .= $this->internal_functions['RINIT']->code;
} else {
$code .= " /* add your stuff here */\n";
}
$code .= "
\treturn SUCCESS;
}
/* }}} */
";
$code .= "
/* {{{ PHP_RSHUTDOWN_FUNCTION */
PHP_RSHUTDOWN_FUNCTION({$this->name})
{
";
if (isset($this->internal_functions['RSHUTDOWN'])) {
$code .= $this->internal_functions['RSHUTDOWN']->code;
} else {
$code .= " /* add your stuff here */\n";
}
$code .= "
\treturn SUCCESS;
}
/* }}} */
";
$code .= "
/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION({$this->name})
{
php_info_print_box_start(0);
";
if (isset($this->logo))
{
$code.= "
php_printf(\"
\\n\");
";
}
if (isset($this->summary)) {
$code .= " php_printf(\"{$this->summary}
\\n\");\n";
}
if (isset($this->release)) {
$code .= " php_printf(\"Version {$this->release['version']}{$this->release['state']} ({$this->release['date']})
\\n\");\n";
}
if (count($this->users)) {
$code .= " php_printf(\"Authors:
\\n\");\n";
foreach ($this->users as $user) {
$code .= " php_printf(\"$user[name] <$user[email]> ($user[role])
\\n\");\n";
}
}
$code.=
" php_info_print_box_end();
";
if (isset($this->internal_functions['MINFO'])) {
$code .= "\n\t{\n";
$code .= $this->internal_functions['MINFO']->code;
$code .= "\n\t}\n";
} else {
$code .= "\t/* add your stuff here */\n";
}
if (count($this->phpini)) {
$code .= "\n\tDISPLAY_INI_ENTRIES();";
}
$code .= "
}
/* }}} */
";
return $code;
}
// }}}
function private_functions_c() {
$code = "";
foreach ($this->private_functions as $name => $func) {
$code .= "\n\t/* {{{ $name() */\n{$func->code}\n\t/* }}} */\n\n";
}
return $code;
}
// {{{ public functions
function public_functions_c() {
$code = "";
foreach ($this->functions as $function) {
$code .= $function->c_code(&$this);
}
return $code;
}
// }}}
// {{{ code file
function write_code_file() {
$filename = "{$this->name}.{$this->language}"; // todo extension logic
$this->files["c"][] = $filename;
$fp = fopen("{$this->name}/$filename", "w");
$upname = strtoupper($this->name);
fputs($fp, $this->get_license());
fputs($fp, "#include \"php_{$this->name}.h\"\n\n");
if (isset($this->logo)) {
fputs($fp, $this->logo->c_code());
}
if (!empty($this->globals)) {
fputs($fp, "ZEND_DECLARE_MODULE_GLOBALS({$this->name})\n\n");
}
fputs($fp, $this->private_functions_c());
if (!empty($this->resources)) {
foreach ($this->resources as $resource) {
fputs($fp, $resource->c_code());
}
}
fputs($fp, "/* {{{ {$this->name}_functions[] */\n");
fputs($fp, "function_entry {$this->name}_functions[] = {\n");
foreach ($this->functions as $name => $function) {
fputs($fp, sprintf("\tPHP_FE(%-20s, NULL)\n",$name));
}
fputs($fp, "\t{ NULL, NULL, NULL }\n");
fputs($fp, "};\n/* }}} */\n\n");
fputs($fp, $this->generate_extension_entry());
fputs($fp, "\n/* {{{ globals and ini entries */\n");
fputs($fp, $this->generate_globals_c());
fputs($fp, "/* }}} */\n\n");
fputs($fp, $this->internal_functions_c());
fputs($fp, $this->public_functions_c());
fputs($fp, $this->editor_config_c());
}
// }}}
// {{{ config.m4 file
function write_config_m4() {
$upname = strtoupper($this->name);
ob_start();
echo
'dnl
dnl $ Id: $
dnl
';
if (isset($this->with['attr'])) {
echo "
PHP_ARG_WITH({$this->name}, whether to enable {$this->name} functions,
[ --with-{$this->name}[=DIR] With {$this->name} support], yes)
";
echo "
if test \"\$PHP_$upname\" != \"no\"; then
if test -r \"\$PHP_$upname/{$this->with['attr']['testfile']}\"; then
PHP_{$upname}_DIR=\"\$PHP_$upname\"
else
AC_MSG_CHECKING(for {$this->name} in default path)
for i in ".str_replace(":"," ",$this->with['attr']['defaults'])."; do
if test -r \"\$i/{$this->with['attr']['testfile']}\"; then
PHP_{$upname}_DIR=\$i
AC_MSG_RESULT(found in \$i)
fi
done
fi
fi
PHP_ADD_INCLUDE(\$PHP_{$upname}_DIR/include)
";
} else {
echo "
PHP_ARG_ENABLE({$this->name} , whether to enable {$this->name} functions,
[ --disable-{$this->name} Disable {$this->name} support], yes)
";
}
echo "\n";
if (count($this->libs)) {
$first = true;
foreach ($this->libs as $lib) {
if (is_array($lib['platform']) && !in_array("unix", $lib['platform'])) {
continue;
}
if ($first) {
echo "PHP_SUBST({$upname}_SHARED_LIBADD)\n\n";
$first = false;
}
if (isset($this->with['attr'])) {
echo "PHP_ADD_LIBRARY_WITH_PATH($lib[name], \$PHP_{$upname}_DIR/lib, {$upname}_SHARED_LIBADD)\n";
} else {
echo "PHP_ADD_LIBRARY($lib[name],, {$upname}_SHARED_LIBADD)\n";
}
if (isset($lib['function'])) {
echo "AC_CHECK_LIB($lib[name], $lib[function], [AC_DEFINE(HAVE_".strtoupper($lib['name']).",1,[ ])], [AC_MSG_ERROR($lib[name] library not found or wrong version)],)\n";
}
}
}
echo "\n";
if ($this->language === "cpp") {
echo "PHP_REQUIRE_CXX\n";
echo "PHP_ADD_LIBRARY(stdc++)\n";
}
echo "
if test \"\$PHP_$upname\" != \"no\"; then
AC_DEFINE(HAVE_$upname, 1, [ ])
PHP_NEW_EXTENSION({$this->name}, ".join(" ", $this->files['c'])." , \$ext_shared)
fi
";
$filename = "{$this->name}/config.m4";
$this->files['conf'][] = basename($filename);
$fp = fopen($filename, "w");
fputs($fp, ob_get_contents());
fclose($fp);
ob_end_clean();
}
// }}}
// {{{ M$ dev studio project file
function write_ms_devstudio_dsp() {
ob_start();
// these system libraries are always needed?
// (list taken from sample *.dsp files in php ext tree...)
$winlibs = "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ";
$winlibs.= "shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib";
// add libraries from section
if (count($this->libs)) {
foreach ($this->libs as $lib) {
if (is_array($lib['platform']) && !in_array("win32", $lib['platform'])) {
continue;
}
$winlibs .= " $lib[name].lib";
}
}
echo
'# Microsoft Developer Studio Project File - Name="'.$this->name.'" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG='.$this->name.' - Win32 Debug_TS
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "'.$this->name.'.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "'.$this->name.'.mak" CFG="'.$this->name.' - Win32 Debug_TS"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "'.$this->name.' - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "'.$this->name.' - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "'.$this->name.' - Win32 Release_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_TS"
# PROP BASE Intermediate_Dir "Release_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TS"
# PROP Intermediate_Dir "Release_TS"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "'.strtoupper($this->name).'_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D "WIN32" /D "PHP_EXPORTS" /D "COMPILE_DL_'.strtoupper($this->name).'" /D ZTS=1 /D HAVE_'.strtoupper($this->name).'=1 /D ZEND_DEBUG=0 /D "NDEBUG" /D "_WINDOWS" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 '.$winlibs.' /nologo /dll /machine:I386
# ADD LINK32 php4ts.lib '.$winlibs.' /nologo /dll /machine:I386 /out:"..\..\Release_TS\php_'.$this->name.'.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
!ELSEIF "$(CFG)" == "'.$this->name.' - Win32 Debug_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_TS"
# PROP BASE Intermediate_Dir "Debug_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_TS"
# PROP Intermediate_Dir "Debug_TS"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "'.strtoupper($this->name).'_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PHP_EXPORTS" /D "COMPILE_DL_'.strtoupper($this->name).'" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_'.strtoupper($this->name).'=1 /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 '.$winlibs.' /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 php4ts_debug.lib '.$winlibs.' /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS\php_'.$this->name.'.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
!ENDIF
# Begin Target
# Name "'.$this->name.' - Win32 Release_TS"
# Name "'.$this->name.' - Win32 Debug_TS"
';
echo '
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
';
foreach ($this->files['c'] as $filename) {
if ($filename{0}!='/' && $filename{0}!='.') {
$filename = "./$filename";
}
$filename = str_replace("/","\\",$filename);
echo "
# Begin Source File
SOURCE=$filename
# End Source File
";
}
echo '
# End Group
';
echo '
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
';
foreach ($this->files['h'] as $filename) {
if ($filename{0}!='/' && $filename{0}!='.') {
$filename = "./$filename";
}
$filename = str_replace("/","\\",$filename);
echo "
# Begin Source File
SOURCE=$filename
# End Source File
";
}
echo
'# End Group
# End Target
# End Project
';
$filename = "{$this->name}/{$this->name}.dsp";
$this->files['conf'][] = basename($filename);
// write file, enforce DOS/Windows line endings on all platforms
$fp = fopen($filename,"wb");
fputs($fp, str_replace("\n","\r\n",ob_get_contents()));
fclose($fp);
ob_end_clean();
}
// }}}
function write_credits() {
if (count($this->users)) {
$this->files['doc'][] = "CREDITS";
$fp = fopen("{$this->name}/CREDITS", "w");
fputs($fp, "{$this->name}\n");
$names = array();
foreach($this->users as $user) {
if (isset($user['name'])) {
$names[] = $user['name'];
}
}
fclose($fp);
}
}
function write_experimental() {
if (isset($this->release['state']) && $this->release['state'] !== 'stable') {
$this->files['doc'][] = "EXPERIMENTAL";
$fp = fopen("{$this->name}/EXPERIMENTAL", "w");
fputs($fp,
"this extension is experimental,
its functions may change their names
or move to extension all together
so do not rely to much on them
you have been warned!
");
fclose($fp);
}
}
function write_package_xml() {
$status = false;
ob_start();
echo
"
{$this->name}
";
if (isset($this->summary)) {
echo " {$this->summary}\n";
}
if (isset($this->description)) {
echo " \n".rtrim($this->description)."\n \n";
}
if (@is_array($this->users)) {
echo "\n \n";
foreach ($this->users as $user) {
echo " \n";
foreach (array("user","name","email","role") as $key) {
if (isset($user[$key])) {
echo " <$key>{$user[$key]}$key>\n";
}
}
echo " \n";
}
echo " \n";
}
if (is_array($this->release)) {
echo "\n \n";
foreach (array("version","date","state","notes") as $key) {
if (isset($this->release[$key])) {
echo " <$key>{$this->release[$key]}$key>\n";
}
}
echo " \n";
}
echo "\n \n";
echo " \n";
if (@is_array($this->files['doc'])) {
foreach ($this->files['doc'] as $file) {
echo " $file\n";
}
}
if (@is_array($this->files['conf'])) {
foreach ($this->files['conf'] as $file) {
echo " $file\n";
}
}
if (@is_array($this->files['c'])) {
foreach ($this->files['c'] as $file) {
echo " $file\n";
}
}
if (@is_array($this->files['h'])) {
foreach ($this->files['h'] as $file) {
echo " $file\n";
}
}
echo " \n";
echo " \n";
echo "\n";
$fp = fopen("{$this->name}/package.xml", "w");
if (is_resource($fp)) {
fputs($fp, ob_get_contents());
fclose($fp);
}
ob_end_clean();
return $status;
}
// }}}
function write_test_files() {
mkdir("$this->name/tests");
foreach ($this->functions as $function) {
$function->write_test($this);
}
}
}
?>