List of Perl’s Win32:: namespace API function I’d like to add (see libwin32).
This code convert XS source code in a PHP extension (Still work in progress).
<?php <?php $xs2phpc_header= <<<EOH /* +----------------------------------------------------------------------+ | Port from Perl's libwin32-0.191 +----------------------------------------------------------------------+ | Author: Eric COLINET <e dot colinet at laposte dot net> | | Author: Perl guys <http://www.perldoc.com/> | +----------------------------------------------------------------------+ */ EOH; $meta= array( 'module' => false, 'prototypes' => false, 'functions' => false, 'header' => false, 'BOOT' => false, ); $file= $argv[1]; //$file= "D:\\local\\src\\libwin32-0.191\\Service\\Service.xs"; //$file= "D:\\local\\src\\libwin32-0.191\\Shortcut\\Shortcut.xs"; /* XS Source parsing */ $f= fopen($file, 'r'); if( !$f ) die("[01] No input file\n"); $cur_func= array(); while( $str= fgets($f, 1024) ) { $str= rtrim($str); if( strpos($str, 'MODULE = ')===0 ) { // if( !ereg('^MODULE = [:A-Z0-9]+ PACKAGE = ([:A-Z0-9]+)$', $str, $m) ) die("[02.1] Unable to parse '$str'"); if( !eregi('^MODULE = [:A-Z0-9]+ PACKAGE = ([:A-Z0-9]+)$', $str, $m) ) die("[02.1] Unable to parse '$str'"); $meta['module']= $m[1]; $meta['prefix']= str_replace('::', '_', $meta['module']); $meta['prefix_uc']= strtoupper($meta['prefix']); continue; } elseif( strpos($str, 'PROTOTYPES: ')===0 ) { if( !eregi('^PROTOTYPES: (.*)$', $str, $m) ) die("[02.2] Unable to parse '$str'"); $meta['prototypes']= $m[1]; continue; } elseif( strpos($str, 'BOOT:')===0 ) { while( $str= trim(fgets($f, 1024)) ) $meta['BOOT'][]= trim($str); continue; } if( !$meta['module'] ) { $meta['header'][]= $str; continue; } if( !$cur_func['type'] ) { if( !trim($str) ) continue; $cur_func['type']= $str; } elseif( !$cur_func['proto'] ) { $cur_func['proto']= $str; if( !eregi('^([_A-Z]+)\(([^)]*)\)', $str, $m) ) die("[03] Can't parse '$str'\n"); $cur_func['name']= $meta['prefix'].'_'.$m[1]; $params= split(' *, *', $m[2]); foreach( $params as $param ) $cur_func['params'][$param]= ''; } elseif( !$cur_func['params_ok'] && !ereg('^ *[A-Z]+:', $str) ) { $found= false; foreach( $cur_func['params'] as $param => $type ) { if( ereg("^([a-zA-Z]+ \*?)$param$", trim($str), $m) ) { $cur_func['params'][$param]= $m[1]; $found= true; break; } } if( !$found ) { die("[04] Can't parse '$str'\n"); } } else { $cur_func['params_ok']= true; if( ereg('^ *([A-Z]+):', $str, $m) ) $cur_func['cur_section']= $m[1]; elseif( $cur_func['cur_section']=='OUTPUT' && !trim($str) ) { unset($cur_func['params_ok']); unset($cur_func['cur_section']); $meta['functions'][]= $cur_func; $cur_func= array(); } else $cur_func[$cur_func['cur_section']][]= $str; } } fclose($f); /* Source creation */ $output= $php_proto= $php_decls= array(); if( is_array($meta['functions']) ) foreach( $meta['functions'] as $func ) { $output[]= "/* {{{ proto {$func['type']} {$func['proto']}"; $output[]= "*/"; $output[]= "PHP_FUNCTION({$func['name']})"; $output[]= "{"; $php_decls[]= "PHP_FUNCTION({$func['name']});"; $php_proto[]= "PHP_FE({$func['name']}, NULL),"; $params_format= ''; $params= ''; foreach( $func['params'] as $name => $value ) { switch( $value ) { case 'long': $type= 'long *'; $params_format.= 'l'; break; case 'char *': $type= 'char **'; $params_format.= 's'; break; default: $type= 'zval *'; $params_format.= 'z'; break; } $params.= ", &$name"; $output[]= "\t$type $name; /* $value */"; } $param_str= '"'.$params_format.'"'.$params; $output[]= "\t".'if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, '.$param_str.') == FAILURE ) { return; }'; if($func['PREINIT']) foreach( $func['PREINIT'] as $pi ) $output[]= $pi; if( $func['CODE'] ) foreach( $func['CODE'] as $code ) $output[]= $code; switch( $func['type'] ) { case 'long': $output[]= "\tRETVAL_LONG(RETVAL);"; break; case 'bool': $output[]= "\tRETVAL_BOOL(RETVAL);"; break; } $output[]= "}"; $output[]= "/* }}} */"; $output[]= ""; } //print_r($output); $module_name= $meta['module']; echo $xs2phpc_header; ?> /* XS module <?=$meta['module']?> */ /* Exported functions: */ #define IS_PHP_EXT 0 #if IS_PHP_EXT #include "php_xs_ext.h" <?=implode("\n", $php_decls)."\n"?> /* {{{ <?=$meta['prefix']?>_functions[] */ function_entry <?=$meta['prefix']?>_functions[] = { <?=implode("\n\t", $php_proto)?> {NULL, NULL, NULL} }; /* }}} */ #ifdef COMPILE_DL_<?=$meta['prefix_uc']?> ZEND_GET_MODULE (<?=$meta['prefix']?>) # ifdef PHP_WIN32 # include "zend_arg_defs.c" # endif #endif /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(<?=$meta['prefix']?>) { php_info_print_table_start(); php_info_print_table_row(2, "<?=$meta['prefix']?> support", "enabled"); php_info_print_table_end(); } /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(<?=$meta['prefix']?>) { <?=implode("\n", $meta['BOOT'])?> return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(<?=$meta['prefix']?>) { return SUCCESS; } /* {{{ <?=$meta['prefix']?>_module_entry */ zend_module_entry <?=$meta['prefix']?>_module_entry = { STANDARD_MODULE_HEADER, "{$meta['name']}", <?=$meta['prefix']?>_functions, PHP_MINIT(<?=$meta['prefix']?>), PHP_MSHUTDOWN(<?=$meta['prefix']?>), NULL, NULL, PHP_MINFO(<?=$meta['prefix']?>), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES }; /* }}} */ #endif // IS_PHP_EXT <? echo implode("\n", $meta['header']); echo implode("\n", $output); ?>