daeken Posted November 9, 2003 Share Posted November 9, 2003 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) Quote Link to comment https://forums.phpfreaks.com/topic/1326-php-extension-code-generator/ Share on other sites More sharing options...
Derek Posted November 9, 2003 Share Posted November 9, 2003 great! this will cut the time of developing extensions by 1/4, atleast idea: int foo(string $bar, int $bleh[, string my_optional_var]); Quote Link to comment https://forums.phpfreaks.com/topic/1326-php-extension-code-generator/#findComment-4397 Share on other sites More sharing options...
daeken Posted November 9, 2003 Author Share Posted November 9, 2003 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) Quote Link to comment https://forums.phpfreaks.com/topic/1326-php-extension-code-generator/#findComment-4400 Share on other sites More sharing options...
metalblend Posted November 9, 2003 Share Posted November 9, 2003 ..had to edit that and change to CODE tags. phpBB\'s PHP tags destroy & and && operators Quote Link to comment https://forums.phpfreaks.com/topic/1326-php-extension-code-generator/#findComment-4405 Share on other sites More sharing options...
daeken Posted November 9, 2003 Author Share Posted November 9, 2003 Ah, thanks. Quote Link to comment https://forums.phpfreaks.com/topic/1326-php-extension-code-generator/#findComment-4408 Share on other sites More sharing options...
Derek Posted November 9, 2003 Share Posted November 9, 2003 great Quote Link to comment https://forums.phpfreaks.com/topic/1326-php-extension-code-generator/#findComment-4411 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.