Jump to content


Photo

Replacement for ext_skel.


  • Please log in to reply
No replies to this topic

#1 daeken

daeken
  • Members
  • PipPip
  • Member
  • 22 posts
  • LocationChambersburg, PA

Posted 09 November 2003 - 07:37 PM

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<?phpfunction 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) . \'_Hextern 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)
Black and white are all I see in my infancy.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users