PEAR::CodeGen_PECL事始め
なかなか触れずにいたんですが、ちょっとだけ時間ができたので使ってみました。
インストールと動作確認
# pear install -a codegen_pecl # pecl-gen Usage: pecl-gen [-h] [--force] [--experimental] [--version] [--extname=name] [--proto=file] [--skel=dir] [--stubs=file] [--no-help] [--xml[=file]] [--full-xml] [--function=proto] [specfile.xml] -h|--help this message -f|--force overwrite existing directories -d|--dir output directory (defaults to extension name) -l|--lint check syntax only, don't create output --linespecs generate #line specs -x|--experimental deprecated --function create a function skeleton from a proto right away --version show version info the following options are inherited from ext_skel: --extname=module module is the name of your extension --proto=file file contains prototypes of functions to create --xml generate xml documentation to be added to phpdoc-cvs these wait for functionality to be implemented and are ignored for now ... --stubs=file generate only function stubs in file --no-help don't try to be nice and create comments in the code and helper functions to test if the module compiled these are accepted for backwards compatibility reasons but not used ... --full-xml generate xml documentation for a self-contained extension (this was also a no-op in ext_skel) --skel=dir path to the skeleton directory (skeleton stuff is now self-contained) #
定義ファイル(specファイル)を作成する
モジュール名をfunction_test01(ベタベタやん。。。)とし、以下の2関数を定義してみます。
- int plus(int x, int y)
- xとyを加算し、結果を返す
- オーバーフローは対処してません ;-)
- string greet([string name])
- 文字列を受け取り、挨拶文の文字列を返す
- パラメータが渡されない・NULL・空文字の場合、固定の挨拶文になる
要素名や属性名を見てもらえれば想像が付くと思います。extension要素が最上位の要素となります。function要素で関数名を定義し、その子のproto要素で関数のcode要素で直接Cのコードを書くこともできます。
#C言語再入門中のため、ツッコミ歓迎です :-)
また、test要素でテストコードを定義することができます。
<?xml version="1.0" ?> <extension name="function_test01" version="1.0.0"> <function name="plus"> <proto>int plus(int x, int y)</proto> <code> long value; value = x + y; RETURN_LONG(value); </code> </function> <function name="greet"> <proto>string greet([string name])</proto> <code> <![CDATA[ const char *msg = "Hello there !\n"; char *s = NULL; if (name != NULL && name_len > 0) { s = emalloc(name_len + strlen(msg) + 1); sprintf(s, "Hello, %s !\n", name); } else { s = msg; } RETURN_STRING(s, 1); efree(s); ]]> </code> </function> <test> <code> <?data echo plus(1, 2); ?> </code> <result mode="format">3</result> </test> <test> <code> <?data echo plus(1, -2); ?> </code> <result mode="format"> -1 </result> </test> <test> <code> <?data echo plus(2147483647, 1); ?> </code> <result mode="format"> -2147483648 </result> </test> <test> <code> <?data echo greet('hoge'); ?> </code> <result mode="format"> Hello, hoge ! </result> </test> <test> <code> <?data echo greet(); ?> </code> <result mode="format"> Hello there ! </result> </test> <test> <code> <?data echo greet(''); ?> </code> <result mode="format"> Hello there ! </result> </test> <test> <code> <?data echo greet(null); ?> </code> <result mode="format"> Hello there ! </result> </test> </extension>
pecl-genを実行し、ひな形コードを生成する
# pecl-gen -f function_test01.xml Creating 'function_test01' extension in './function_test01' Your extension has been created in directory ./function_test01. See ./function_test01/README and ./function_test01/INSTALL for further instructions. #
他の拡張モジュールと同様の手順でbuild・インストール
# cd function_test01 # phpize # ./configure --enable-function-test01 # make install #
php.iniを編集する
# echo "extension=function_test01.so" >> /path/to/php-cli.ini
テストを実行する
# php ./run-tests.php ===================================================================== CWD : /home/shimooka/public_html/codegen_pecl/function_test01 PHP : /usr/local/lib/php5/bin/php PHP_SAPI : cli PHP_VERSION : 5.2.0RC5 ZEND_VERSION: 2.2.0 PHP_OS : Linux - Linux ofnir 2.6.9-42.0.3.ELsmp #1 SMP Fri Oct 6 06:21:39 CDT 2006 i686 INI actual : /usr/local/lib/php5/ini/5.2.0/php-cli.ini More .INIs : Extra dirs : ===================================================================== TIME START 2006-10-30 18:15:35 ===================================================================== PASS 001 [tests/001.phpt] PASS 002 [tests/002.phpt] PASS 003 [tests/003.phpt] PASS 004 [tests/004.phpt] PASS 005 [tests/005.phpt] PASS 006 [tests/006.phpt] PASS 007 [tests/007.phpt] PASS greet() function [tests/greet.phpt] PASS plus() function [tests/plus.phpt] ===================================================================== TIME END 2006-10-30 18:15:35 ===================================================================== TEST RESULT SUMMARY --------------------------------------------------------------------- Exts skipped : 0 Exts tested : 30 --------------------------------------------------------------------- Number of tests : 9 9 Tests skipped : 0 ( 0.0%) -------- Tests warned : 0 ( 0.0%) ( 0.0%) Tests failed : 0 ( 0.0%) ( 0.0%) Tests passed : 9 (100.0%) (100.0%) --------------------------------------------------------------------- Time taken : 0 seconds ===================================================================== You may have found a problem in PHP. We would like to send this report automatically to the PHP QA team, to give us a better understanding of how the test cases are doing. If you don't want to send it immediately, you can choose "s" to save the report to a file that you can send us later. Do you want to send this report now? [Yns]: n #
使ってみた感想
ext_skelスクリプトも便利でしたが、これ。。。めちゃくちゃ便利ですね。今回は非常に簡単な関数でしたが、自動生成されたCファイルは全く編集する必要がありませんでした。あと、テストスクリプト(phptファイル)も生成でき、run-tests.phpまで用意されます。
今回は、specファイル(function_test01.xml)のひな形として、cvs.php.netのexamplesにあったspecファイルを使いました。ここには色々なspecファイルの例がありますので、specファイルを書く参考になります。
しかし、何でアーカイブに入ってないんだろ?是非とも入れて欲しいな :-)