Jump to content

daeken

Members
  • Posts

    22
  • Joined

  • Last visited

    Never

Contact Methods

  • Website URL
    http://www.alleykatsoft.com/

Profile Information

  • Gender
    Not Telling
  • Location
    Chambersburg, PA

daeken's Achievements

Newbie

Newbie (1/5)

0

Reputation

  1. This _could_ be done... however, this would mean you couldn't let PHP access them directly, like an object. If it's just for internal use, go for it, otherwise I'd stick with normal objects. Happy Hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  2. First, I suggest you not use AOLbonics like '4' in place of 'for' and others as laziness is one of the attributes a programmer can _not_ afford to have. Second, don't use caps, it's offensive and your question is _not_ that important. Third, there are many entries on the php-dev mailing list about the basics of extension building for windows, and my ext_skel replacement will help you quite a bit. Happy Hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  3. I recently was pointed to the Amygdala spiking neural network library http://amygdala.sf.net/ for some AI stuff I was doing. I decided that PHP deserved to have an extension for this great C++ library, so I started working on it. I'm using my ext_skel replacement to ease the development, and that's nice so far (adding C++ support and class parameters, and I'll release it when I'm done, of course), but I've hit quite the brick wall... you create an instance of the LayerConstants class and set the parameters for the first layer, then create it and add it to the network, then you set the parameters in the LayerConstants object for the next layer, and so on and so forth. The problem is, I have no idea how I should keep track of what LayerConstants object I should be looking at, or how to get it from userspace. Perhaps I could just make any changes to the PHP instance of the LayerConstants change an instance of the C++ object somewhere in my code, if so, is there a way to have a function called when a parameter is changed in an extension (similar to __set() in normal PHP code)? Looking forward to any advise on the subject. Cheers, Lord Daeken M. BlackBlade (Cody Brocious)
  4. If you\'re processing the code, you should have absolutely no problem identifying code blocks... if you can\'t do that, then you really need to think about the way your processor works.
  5. I\'ve played with it a bit and haven\'t had any issues (except with thread safety). If you post your code here, i may be able to help you find the problem
  6. I\'ve come up with a replacement for ext_skel, based upon my code generator. It generates the header, C source, and config.m4 for you, with or without function definitions. --Edit-- Put up the new code which supports resources, constants, and classes! --Edit-- #!/usr/local/bin/php <?php function Gen($file, $extname) { $defs = array(); $res = array(); $const = array(); foreach($file as $line) { $parts = explode(\' \', trim($line)); $arr = array(); if(!preg_match(\'/^[s]*(#([^s]+)[s]+([^s]+)[s]+(.*)$|(void|int|float|double|bool|resource|array|object|mixed)[s]+([^:]*::)?([^(]+)(([^)]*));[s]*(.*))$/\', trim($line), $matches)) continue; if(!empty($matches[1]) && $matches[1][0] == \'#\') { if($matches[2] == \'resource\') $res[$matches[3]] = $matches[4]; elseif($matches[2] == \'define\') $const[$matches[3]] = $matches[4]; continue; } $arr[\'return\'] = $matches[5]; $arr[\'class\'] = substr($matches[6], 0, -2); $arr[\'name\'] = $matches[7]; $arr[\'params\'] = array(); $arr[\'desc\'] = $matches[9]; $last = 0; $opt = false; preg_match_all(\'/([|])?[s]*(.+?)[s]+$([^s[],=]+)[s]*=?[s]*([^s[]]*)[s]*([|])*,?[s]*/\', $matches[8], $matches); for($i = 0; $i < count($matches[0]); ++$i) { $type = $matches[2][$i]; $name = $matches[3][$i]; $def = $matches[4][$i]; if($matches[1][$i] == \'[\') $opt = $tempopt = true; elseif($matches[5][$i] == \'[\') $tempopt = true; elseif($matches[5][$i] == \']\' || empty($matches[5][$i])) $tempopt = false; $arr[\'params\'][$name] = array($type, $opt, $def); $opt = $tempopt; } $defs[] = $arr; } ob_start(); foreach($defs as $arr) { echo \'PHP_FUNCTION(\', $arr[\'name\']; if(!empty($arr[\'class\'])) echo \'_\'; echo \');\', NL; } $def = ob_get_contents(); ob_end_clean(); ob_start(); $objs = array(); foreach($defs as $arr) { if(!isset($objs[$arr[\'class\']])) $objs[$arr[\'class\']] = array(); $objs[$arr[\'class\']][] = $arr[\'name\']; } $minit = (string) null; foreach($res as $name => $text) { echo \'static int le_\', $name, \'_res;\', NL, \'static void _free_foobar_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)\', NL, \'{\', NL, \'}\', NL, NL; $minit .= \' le_\' . $name . \'_res = zend_register_list_destructors_ex(_free_\' . $name . \'_result, NULL, \' . $text . \', module_number);\' . NL; } foreach($const as $name => $val) { if($val[0] == \'"\') $type = \'STRING\'; elseif(strstr($val, \'.\')) $type = \'DOUBLE\'; else $type = \'LONG\'; $minit .= \' REGISTER_\' . $type . \'_CONSTANT("\' . $name . \'", \' . $val . \', CONST_CS | CONST_PERSISTENT);\' . NL; } echo NL; foreach($objs as $class => $funcs) { if(empty($class)) echo \'function_entry \', $extname, \'_functions[] = {\', NL; else { echo \'zend_class_entry \', $class, \'_class_entry;\', NL; echo \'function_entry \', $class, \'_class_functions[] = {\', NL; $minit .= \' INIT_CLASS_ENTRY(\' . $class . \'_class_entry, "\' . $class . \'", \' . $class . \'_class_functions);\' . NL . \' zend_register_internal_class(&\' . $class . \'_class_entry TSRMLS_CC);\' . NL; } foreach($funcs as $func) { if(empty($class)) echo \' ZEND_FE(\', $func, \', NULL)\', NL; else echo \' ZEND_FALIAS(\', $func, \', \', $func, \'_, NULL)\', NL; } echo \' {NULL, NULL, NULL}\', NL, \'};\', NL, NL, NL; } if(!isset($objs[\'\'])) echo \'function_entry \', $extname, \'_functions[] = {\', NL, \' {NULL, NULL, NULL}\', NL, \'};\', NL, NL, NL; $entry = ob_get_contents(); ob_end_clean(); ob_start(); foreach($defs as $arr) { echo \'/* {{{ proto \', $arr[\'return\'], \' \'; if(!empty($arr[\'class\'])) echo $arr[\'class\'], \'::\'; echo $arr[\'name\'], \'(\'; $i = 0; $optcount = 0; foreach($arr[\'params\'] as $name => $temp) { list($type, $opt, $default) = $temp; if(!$opt) { echo str_repeat(\']\', $optcount); $optcount = 0; } if($opt) { if($i != 0) echo \' \'; echo \'[\'; ++$optcount; } if(++$i > 1) echo \', \'; echo $type, \' \', $name; if($opt && !empty($default)) echo \' = \', $default; } echo str_repeat(\']\', $optcount); echo \')\', NL, \' \', $arr[\'desc\'], \' */\', NL, \'PHP_FUNCTION(\', $arr[\'name\']; if(!empty($arr[\'class\'])) echo \'_\'; echo \')\', NL, \'{\', NL; $format = (string) null; $params = (string) null; $i = 0; foreach($arr[\'params\'] as $name => $temp) { list($type, $opt, $default) = $temp; switch($type) { case \'int\': echo \' int \', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = 0\'; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'l\'; $params .= \'&\' . $name; break; case \'string\': echo \' char *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', NL, \' int \', $name, \'_len\'; if($opt && !empty($default)) echo \' = \', strlen($default) - 2; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'s\'; $params .= \'&\' . $name . \', &\' . $name . \'_len\'; break; case \'bool\': case \'boolean\': echo \' zend_bool \', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = FALSE\'; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'b\'; $params .= \'&\' . $name; break; case \'array\': echo \' zval *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'a\'; $params .= \'&\' . $name; break; case \'mixed\': case \'resource\': echo \' zval *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'z\'; $params .= \'&\' . $name; break; case \'object\': echo \' zval *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'o\'; $params .= \'&\' . $name; break; case \'double\': case \'float\': echo \' double \', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = 0\'; echo \';\', NL; if($opt) $format .= \'|\'; $format .= \'d\'; $params .= \'&\' . $name; break; } if(++$i != count($arr[\'params\'])) $params .= \', \'; } $need = 0; foreach($arr[\'params\'] as $name => $temp) { if(!$temp[1]) ++$need; } if(count($arr[\'params\']) > 0) echo \' if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "\', $format, \'", \', $params, \') == FAILURE)\', NL, \' return;\', NL, \'}\', NL, NL; else echo \'}\', NL, \'/* }}} */\', NL, NL; } $funcs = ob_get_contents(); ob_end_clean(); return array($def, $entry, $funcs, $minit); } function Get() { return trim(fgets(STDIN)); } define(\'NL\', chr(10)); echo \'Welcome to the extension builder.\', NL, \'To get started, type the name of your extension.\', NL; $ext = Get(); $foo = false; echo \'Ok. To get started with making extension `\', $ext, \'\' we will make the directory.\', NL; while(!$foo) { echo \'Please give the path to the ext/ directory of the PHP source tree.\', NL; $dir = Get(); $foo = is_dir($dir); } @mkdir($dir . \'/\' . $ext); echo \'Extension directory created.\', NL, \'What is your name?\', NL; $author = str_pad(Get(), 61, \' \', STR_PAD_RIGHT); echo \'What libraries (if any) are needed by this extension? (space-seperated only please)\', NL; $libs = explode(\' \', Get()); echo \'What includes (if any) are needed by this extension? (space-seperated only please)\', NL; $incs = explode(\' \', Get()); while(true) { echo \'What is the filename of your function definition file? (leave blank if you don\'t have one)\', NL; $def = Get(); if(empty($def)) { $file = array(); break; } if(!empty($def) && !file_exists($def)) echo \'File does not exist.\', NL; else { $file = file($def); break; } } while(true) { echo \'Do you want --with-\', $ext, \' or --enable-\', $ext, \' ? (Enter either with or enable)\', NL; $flag = strtolower(Get()); if($flag == \'with\' || $flag == \'enable\') break; } $head = fopen($dir . \'/\' . $ext . \'/php_\' . $ext . \'.h\', \'w\'); ob_start(); echo \'/*\', NL, \' +----------------------------------------------------------------------+\', NL, \' | PHP Version 4 |\', NL, \' +----------------------------------------------------------------------+\', NL, \' | Copyright (c) 1997-2003 The PHP Group |\', NL, \' +----------------------------------------------------------------------+\', NL, \' | This source file is subject to version 2.02 of the PHP license, |\', NL, \' | that is bundled with this package in the file LICENSE, and is |\', NL, \' | available at through the world-wide-web at |\', NL, \' | http://www.php.net/license/2_02.txt. |\', NL, \' | If you did not receive a copy of the PHP license and are unable to |\', NL, \' | obtain it through the world-wide-web, please send a note to |\', NL, \' | license@php.net so we can mail you a copy immediately. |\', NL, \' +----------------------------------------------------------------------+\', NL, \' | Author: \', $author, \'|\', NL, \' +----------------------------------------------------------------------+\', NL, \' $Id: header,v 1.10.8.1 2003/07/14 15:59:18 sniper Exp $ \', NL, \'*/\', NL, NL; $fileheader = ob_get_contents(); ob_end_clean(); $h = \'#ifndef PHP_\' . strtoupper($ext) . \'_H #define PHP_\' . strtoupper($ext) . \'_H extern zend_module_entry \' . $ext . \'_module_entry; #define phpext_\' . $ext . \'_ptr &\' . $ext . \'_module_entry #ifdef PHP_WIN32 #define PHP_\' . strtoupper($ext) . \'_API __declspec(dllexport) #else #define PHP_\' . strtoupper($ext) . \'_API #endif #ifdef ZTS #include "TSRM.h" #endif \' . NL; foreach($incs as $include) if(!empty($include)) $h .= \'#include <\' . $include . \'>\' . NL; $h .= NL . \'PHP_MINIT_FUNCTION(\' . $ext . \'); PHP_MSHUTDOWN_FUNCTION(\' . $ext . \'); PHP_RINIT_FUNCTION(\' . $ext . \'); PHP_RSHUTDOWN_FUNCTION(\' . $ext . \'); PHP_MINFO_FUNCTION(\' . $ext . \');\' . NL . NL; fwrite($head, $fileheader); fwrite($head, $h); list($defs, $entry, $funcs, $minit) = Gen($file, $ext); fwrite($head, $defs); fwrite($head, \'#endif\' . NL); fclose($head); $source = fopen($dir . \'/\' . $ext . \'/\' . $ext . \'.c\', \'w\'); fwrite($source, $fileheader); $c = \'#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_\' . $ext . \'.h" /* True global resources - no need for thread safety here */ static int le_\' . $ext . \';\' . NL . NL; fwrite($source, $c); fwrite($source, $entry); $c = \'/* {{{ \' . $ext . \'_module_entry */ zend_module_entry \' . $ext . \'_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "\' . $ext . \'", \' . $ext . \'_functions, PHP_MINIT(\' . $ext . \'), PHP_MSHUTDOWN(\' . $ext . \'), PHP_RINIT(\' . $ext . \'), /* Replace with NULL if there\'s nothing to do at request start */ PHP_RSHUTDOWN(\' . $ext . \'), /* Replace with NULL if there\'s nothing to do at request end */ PHP_MINFO(\' . $ext . \'), #if ZEND_MODULE_API_NO >= 20010901 "0.1", /* Replace with version number for your extension */ #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_\' . strtoupper($ext) . \' ZEND_GET_MODULE(\' . $ext . \') #endif /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(\' . $ext . \') { \' . $minit . \' return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(\' . $ext . \') { return SUCCESS; } /* }}} */ /* Remove if there\'s nothing to do at request start */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(\' . $ext . \') { return SUCCESS; } /* }}} */ /* Remove if there\'s nothing to do at request end */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(\' . $ext . \') { return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(\' . $ext . \') { php_info_print_table_start(); php_info_print_table_header(2, "\' . $ext . \' support", "enabled"); php_info_print_table_end(); } /* }}} */\' . NL . NL; fwrite($source, $c); fwrite($source, $funcs); fclose($source); $m4 = fopen($dir . \'/\' . $ext . \'/config.m4\', \'w\'); if($flag == \'enable\') fwrite($m4, \'PHP_ARG_ENABLE(\' . $ext . \', for \' . $ext . \' support,\' . NL . \'[ --enable-\' . $ext . \' Enable \' . $ext . \' support])\' . NL); else fwrite($m4, \'PHP_ARG_WITH(\' . $ext . \', for \' . $ext . \' support,\' . NL . \'[ --with-\' . $ext . \' Include \' . $ext . \' support])\' . NL); fwrite($m4, \'if test "$PHP_\' . strtoupper($ext) . \'" != "no"; then\' . NL); foreach($libs as $lib) { if(!empty($lib)) fwrite($m4, \' PHP_CHECK_LIBRARY(\' . $lib . \',\' . $lib . \',\' . NL . \' [\' . NL . \' AC_DEFINE(HAVE_\' . strtoupper($ext) . \'LIB,1,[ ])\' . NL . \' ],[\' . NL . \' AC_MSG_ERROR([wrong \' . $lib . \' lib version of lib not found])\' . NL . \' ],[\' . NL . \' -l\' . $lib . NL . \' ])\' . NL . \' PHP_ADD_LIBRARY_WITH_PATH(\' . $ext . \', /usr/lib, \' . strtoupper($ext) . \'_SHARED_LIBADD)\' . NL); } fwrite($m4, \' PHP_NEW_EXTENSION(\' . $ext . \', \' . $ext . \'.c, $ext_shared)\' . NL . \'fi\' . NL); fclose($m4); ?> Example definition file: void SomeClass::Foo(int $bar); Description! #define foo "bar" #resource foobar "Foobar Resource" Have fun! Happy hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  7. New version, new parser, and a new feature: optional parameters. #!/usr/local/bin/php <?php if($_SERVER[\'argc\'] < 3) { echo \'Usage: \', $_SERVER[\'argv\'][0], \' <extension name> <definition>\', chr(10); exit; } $file = file($_SERVER[\'argv\'][2]); $defs = array(); foreach($file as $line) { $parts = explode(\' \', trim($line)); $arr = array(); $arr[\'return\'] = $parts[0]; $arr[\'name\'] = substr($parts[1], 0, strpos($parts[1], \'(\')); $arr[\'params\'] = array(); $arr[\'desc\'] = trim(substr($line, strpos($line, \';\') + 1)); $pos = strpos($line, \'(\') + 1; $line = trim(substr($line, $pos, strrpos($line, \')\') - $pos)); $last = 0; $opt = false; preg_match_all(\'/([|])?[s]*(.+?)[s]+$([^s[],=]+)[s]*=?[s]*([^s[]]*)[s]*([|])*,?[s]*/\', $line, $matches); for($i = 0; $i < count($matches[0]); ++$i) { $type = $matches[2][$i]; $name = $matches[3][$i]; $def = $matches[4][$i]; if($matches[1][$i] == \'[\') $opt = $tempopt = true; elseif($matches[5][$i] == \'[\') $tempopt = true; elseif($matches[5][$i] == \']\' || empty($matches[5][$i])) $tempopt = false; $arr[\'params\'][$name] = array($type, $opt, $def); $opt = $tempopt; } $defs[] = $arr; } echo \'function_entry \', $_SERVER[\'argv\'][1], \'_functions[] = {\', chr(10); foreach($defs as $arr) echo \' ZEND_FE(\', $arr[\'name\'], \', NULL)\', chr(10); echo \' {NULL, NULL, NULL}\', chr(10), \'};\', chr(10), chr(10), chr(10); foreach($defs as $arr) { echo \'/* {{{ proto \', $arr[\'return\'], \' \', $arr[\'name\'], \'(\'; $i = 0; $optcount = 0; foreach($arr[\'params\'] as $name => $temp) { list($type, $opt, $default) = $temp; if(!$opt) { echo str_repeat(\']\', $optcount); $optcount = 0; } if($opt) { if($i != 0) echo \' \'; echo \'[\'; ++$optcount; } if(++$i > 1) echo \', \'; echo $type, \' \', $name; if($opt && !empty($default)) echo \' = \', $default; } echo str_repeat(\']\', $optcount); echo \')\', chr(10), \' \', $arr[\'desc\'], \' */\', chr(10), \'PHP_FUNCTION(\', $arr[\'name\'], \')\', chr(10), \'{\', chr(10); $format = (string) null; $params = (string) null; $i = 0; foreach($arr[\'params\'] as $name => $temp) { list($type, $opt, $default) = $temp; switch($type) { case \'int\': echo \' int \', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = 0\'; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'l\'; $params .= \'&\' . $name; break; case \'string\': echo \' char *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', chr(10), \' int \', $name, \'_len\'; if($opt && !empty($default)) echo \' = \', strlen($default) - 2; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'s\'; $params .= \'&\' . $name . \', &\' . $name . \'_len\'; break; case \'bool\': case \'boolean\': echo \' zend_bool \', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = FALSE\'; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'b\'; $params .= \'&\' . $name; break; case \'array\': echo \' zval *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'a\'; $params .= \'&\' . $name; break; case \'mixed\': case \'resource\': echo \' zval *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'z\'; $params .= \'&\' . $name; break; case \'object\': echo \' zval *\', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = NULL\'; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'o\'; $params .= \'&\' . $name; break; case \'double\': case \'float\': echo \' double \', $name; if($opt && !empty($default)) echo \' = \', $default; elseif($opt) echo \' = 0\'; echo \';\', chr(10); if($opt) $format .= \'|\'; $format .= \'d\'; $params .= \'&\' . $name; break; } if(++$i != count($arr[\'params\'])) $params .= \', \'; } $need = 0; foreach($arr[\'params\'] as $name => $temp) { if(!$temp[1]) ++$need; } echo \' if(ZEND_NUM_ARGS() < \', $need, \') WRONG_PARAM_COUNT;\', chr(10), \' if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "\', $format, \'", \', $params, \') == FAILURE)\', chr(10), \' return;\', chr(10), \'}\', chr(10), chr(10); } ?> Example definition: int foo(string $bar[, int $bleh]); Simple function! bool is_even([mixed $var = 5]); Checks if a variable is even. Output: function_entry openal_functions[] = { ZEND_FE(foo, NULL) ZEND_FE(is_even, NULL) {NULL, NULL, NULL} }; /* {{{ proto int foo(string bar [, int bleh]) Simple function! */ PHP_FUNCTION(foo) { char *bar; int bar_len; int bleh = 0; if(ZEND_NUM_ARGS() < 1) WRONG_PARAM_COUNT; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &bar, &bar_len, &bleh) == FAILURE) return; } /* {{{ proto bool is_even([mixed var = 5]) Checks if a variable is even. */ PHP_FUNCTION(is_even) { zval *var = 5; if(ZEND_NUM_ARGS() < 0) WRONG_PARAM_COUNT; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &var) == FAILURE) return; } Have fun! Happy hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  8. Well, after about half an hour of work, I have a full rewrite of my skeleton generator. This time, instead of a C header file, you create a function definition file. Example: int foo(string $bar, int $bleh); Simple function! bool is_even(mixed $var); Checks if a variable is even. Another notable difference is that it generates full documentation in the C code, and parses parameters. Example output of that above definition file is: function_entry openal_functions[] = { ZEND_FE(foo, NULL) ZEND_FE(is_even, NULL) {NULL, NULL, NULL} }; /* {{{ proto int foo(string bar, int bleh) Simple function! */ PHP_FUNCTION(foo) { char *bar; int bar_len; int bleh; if(ZEND_NUM_ARGS() < 2) WRONG_PARAM_COUNT; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &bar, &bar_len, &bleh) == FAILURE) return; } /* {{{ proto bool is_even(mixed var) Checks if a variable is even. */ PHP_FUNCTION(is_even) { zval *var; if(ZEND_NUM_ARGS() < 1) WRONG_PARAM_COUNT; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &var) == FAILURE) return; } As you can see, this does all the really hard work for you, leading to more efficient extension building And now for the code... [php:1:7617edc449] #!/usr/local/bin/php <?php if($_SERVER[\'argc\'] < 3) { echo \'Usage: \', $_SERVER[\'argv\'][0], \' <extension name> <definition>\', chr(10); exit; } $file = file($_SERVER[\'argv\'][2]); $defs = array(); foreach($file as $line) { $parts = explode(\' \', trim($line)); $arr = array(); $arr[\'return\'] = $parts[0]; $arr[\'name\'] = substr($parts[1], 0, strpos($parts[1], \'(\')); $arr[\'params\'] = array(); $arr[\'desc\'] = trim(substr($line, strpos($line, \';\') + 1)); $pos = strpos($line, \'(\') + 1; $line = substr($line, $pos, strrpos($line, \')\') - $pos); $params = explode(\',\', $line); foreach($params as $part) { list($type, $name) = explode(\' \', trim($part)); $arr[\'params\'][str_replace(\'$\', (string) null, $name)] = $type; } $defs[] = $arr; } echo \'function_entry \', $_SERVER[\'argv\'][1], \'_functions[] = {\', chr(10); foreach($defs as $arr) echo \' ZEND_FE(\', $arr[\'name\'], \', NULL)\', chr(10); echo \' {NULL, NULL, NULL}\', chr(10), \'};\', chr(10), chr(10), chr(10); foreach($defs as $arr) { echo \'/* {{{ proto \', $arr[\'return\'], \' \', $arr[\'name\'], \'(\'; $i = 0; foreach($arr[\'params\'] as $name => $type) { echo $type, \' \', $name; if(++$i != count($arr[\'params\'])) echo \', \'; } echo \')\', chr(10), \' \', $arr[\'desc\'], \' */\', chr(10), \'PHP_FUNCTION(\', $arr[\'name\'], \')\', chr(10), \'{\', chr(10); $format = (string) null; $params = (string) null; $i = 0; foreach($arr[\'params\'] as $name => $type) { switch($type) { case \'int\': echo \' int \', $name, \';\', chr(10); $format .= \'l\'; $params .= \'&\' . $name; break; case \'string\': echo \' char *\', $name, \';\', chr(10), \' int \', $name, \'_len;\', chr(10); $format .= \'s\'; $params .= \'&\' . $name . \', &\' . $name . \'_len\'; break; case \'bool\': case \'boolean\': echo \' zend_bool \', $name, \';\', chr(10); $format .= \'b\'; $params .= \'&\' . $name; break; case \'array\': echo \' zval *\', $name, \';\', chr(10); $format .= \'a\'; $params .= \'&\' . $name; break; case \'mixed\': case \'resource\': echo \' zval *\', $name, \';\', chr(10); $format .= \'z\'; $params .= \'&\' . $name; break; case \'object\': echo \' zval *\', $name, \';\', chr(10); $format .= \'o\'; $params .= \'&\' . $name; break; case \'double\': case \'float\': echo \' double \', $name, \';\', chr(10); $format .= \'d\'; $params .= \'&\' . $name; break; } if(++$i != count($arr[\'params\'])) $params .= \', \'; } echo \' if(ZEND_NUM_ARGS() < \', count($arr[\'params\']), \') WRONG_PARAM_COUNT;\', chr(10), \' if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"\', $format, \'\", \', $params, \') == FAILURE)\', chr(10), \' return;\', chr(10), \'}\', chr(10), chr(10); } ?> [/php:1:7617edc449] Have fun Happy hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  9. Just an example header file and the skeleton code generated: /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.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: Cody Brocious | +----------------------------------------------------------------------+ $Id: header,v 1.10.8.1 2003/07/14 15:59:18 sniper Exp $ */ #ifndef PHP_OPENAL_H #define PHP_OPENAL_H extern zend_module_entry openal_module_entry; #define phpext_openal_ptr &openal_module_entry #ifdef PHP_WIN32 #define PHP_OPENAL_API __declspec(dllexport) #else #define PHP_OPENAL_API #endif #ifdef ZTS #include "TSRM.h" #endif #include <AL/al.h> PHP_MINIT_FUNCTION(openal); PHP_MSHUTDOWN_FUNCTION(openal); PHP_RINIT_FUNCTION(openal); PHP_RSHUTDOWN_FUNCTION(openal); PHP_MINFO_FUNCTION(openal); PHP_FUNCTION(alEnable); PHP_FUNCTION(alDisable); PHP_FUNCTION(alIsEnabled); PHP_FUNCTION(alHint); PHP_FUNCTION(alGetBooleanv); PHP_FUNCTION(alGetIntegerv); #ifdef ZTS #define OPENAL_G(v) TSRMG(openal_globals_id, zend_openal_globals *, v) #else #define OPENAL_G(v) (openal_globals.v) #endif #endif /* PHP_OPENAL_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: t * End: */ Skeleton Code: function_entry openal_functions[] = { ZEND_FE(alEnable, NULL) ZEND_FE(alDisable, NULL) ZEND_FE(alIsEnabled, NULL) ZEND_FE(alHint, NULL) ZEND_FE(alGetBooleanv, NULL) ZEND_FE(alGetIntegerv, NULL) {NULL, NULL, NULL} }; /* {{{ proto void alEnable() DESCRIPTION */ PHP_FUNCTION(alEnable) { } /* }}} */ /* {{{ proto void alDisable() DESCRIPTION */ PHP_FUNCTION(alDisable) { } /* }}} */ /* {{{ proto void alIsEnabled() DESCRIPTION */ PHP_FUNCTION(alIsEnabled) { } /* }}} */ /* {{{ proto void alHint() DESCRIPTION */ PHP_FUNCTION(alHint) { } /* }}} */ /* {{{ proto void alGetBooleanv() DESCRIPTION */ PHP_FUNCTION(alGetBooleanv) { } /* }}} */ /* {{{ proto void alGetIntegerv() DESCRIPTION */ PHP_FUNCTION(alGetIntegerv) { } /* }}} */
  10. I was whipping up a quick OpenAL extension, so I started by writing the php_openal.h file and adding the appropriate PHP_FUNCTION(...); lines... well, soon after I got the idea of taking that header file and generating base code for the extension itself from it. Here\'s what I ended up with: [php:1:88128bd8ea] #!/usr/local/bin/php <?php if($_SERVER[\'argc\'] < 3) { echo \'Usage: \', $_SERVER[\'argv\'][0], \' <extension name> <header file>\', chr(10); exit; } $file = file($_SERVER[\'argv\'][2]); $funcs = array(); foreach($file as $line) { $line = trim($line); if(substr($line, 0, 13) == \'PHP_FUNCTION(\') $funcs[] = substr($line, 13, -2); } echo \'function_entry \', $_SERVER[\'argv\'][1], \'_functions[] = {\', chr(10); foreach($funcs as $foo) echo \' ZEND_FE(\', $foo, \', NULL)\', chr(10); echo \' {NULL, NULL, NULL}\', chr(10), \'};\', chr(10), chr(10), chr(10); foreach($funcs as $foo) echo \'/* {{{ proto void \', $foo, \'()\', chr(10), \' DESCRIPTION */\', chr(10), chr(10), \'PHP_FUNCTION(\', $foo, \')\', chr(10), \'{\', chr(10), \'}\', chr(10), \'/* }}} */\', chr(10), chr(10); ?> [/php:1:88128bd8ea] Have fun with it, and as always Happy hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  11. I must note that you can develop PHP extensions on non-linux platforms, although documentation on doing so is sparse for the most part. My guide series is covering all platforms that PHP will run on Happy Hacking, Lord Daeken M. BlackBlade (Cody Brocious)
  12. Welcome! Perhaps the manual would be helpful, as it explains basic core hacking quite well (although everything after that is explained very very poorly). Check it out at http://phpfreaks.com/phpmanual/page/zend.html . Happy hacking, Daeken M. BlackBlade (Cody Brocious)
  13. daeken

    Smarty++

    hmm... perhaps i will later today.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.