commit
1d693e4f16
47 changed files with 1447 additions and 7 deletions
21
.travis.yml
21
.travis.yml
|
|
@ -38,12 +38,31 @@ matrix:
|
|||
language: perl
|
||||
perl: "5.10"
|
||||
env: BINDINGS=perl CC=clang
|
||||
- compiler: gcc
|
||||
language: php
|
||||
php: "5.5"
|
||||
env: BINDINGS=php
|
||||
- compiler: clang
|
||||
language: php
|
||||
php: "5.5"
|
||||
env: BINDINGS=php CC=clang
|
||||
- compiler: gcc
|
||||
language: php
|
||||
php: "5.4"
|
||||
env: BINDINGS=php
|
||||
- compiler: clang
|
||||
language: php
|
||||
php: "5.4"
|
||||
env: BINDINGS=php CC=clang
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- if [ "$BINDINGS" != "none" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; swig -version; fi
|
||||
- if [ "$BINDINGS" != "none" ]; then sudo apt-get install -qq swig; fi
|
||||
- if [ "$BINDINGS" == "perl" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; fi
|
||||
- if [ "$BINDINGS" == "python" ]; then sudo apt-get install -qq python-dev; fi
|
||||
|
||||
install: true
|
||||
before_script:
|
||||
- if [ "$BINDINGS" == "php" ]; then phpenv config-add src/bindings/php/hammer.ini; fi
|
||||
script:
|
||||
- scons bindings=$BINDINGS test
|
||||
notifications:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import sys
|
|||
vars = Variables(None, ARGUMENTS)
|
||||
vars.Add(PathVariable('DESTDIR', "Root directory to install in (useful for packaging scripts)", None, PathVariable.PathIsDirCreate))
|
||||
vars.Add(PathVariable('prefix', "Where to install in the FHS", "/usr/local", PathVariable.PathAccept))
|
||||
vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['python', 'perl']))
|
||||
vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['python', 'perl', 'php']))
|
||||
|
||||
env = Environment(ENV = {'PATH' : os.environ['PATH']}, variables = vars, tools=['default', 'scanreplace'], toolpath=['tools'])
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ dbg = env.Clone(VARIANT='debug')
|
|||
dbg.Append(CCFLAGS=['-g'])
|
||||
|
||||
opt = env.Clone(VARIANT='opt')
|
||||
opt.Append(CCFLAGS="-O3")
|
||||
opt.Append(CCFLAGS=["-O3"])
|
||||
|
||||
if GetOption("variant") == 'debug':
|
||||
env = dbg
|
||||
|
|
@ -95,6 +95,7 @@ env["ENV"].update(x for x in os.environ.items() if x[0].startswith("CCC_"))
|
|||
#env.Append(CPPPATH=os.path.join('#', "hammer"))
|
||||
|
||||
testruns = []
|
||||
|
||||
targets = ["$libpath",
|
||||
"$incpath",
|
||||
"$parsersincpath",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ Import('env')
|
|||
example = env.Clone()
|
||||
example.Append(LIBS="hammer", LIBPATH="../src")
|
||||
|
||||
example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c'])
|
||||
example.Program('base64', 'base64.c')
|
||||
example.Program('base64_sem1', 'base64_sem1.c')
|
||||
example.Program('base64_sem2', 'base64_sem2.c')
|
||||
dns = example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c'])
|
||||
base64 = example.Program('base64', 'base64.c')
|
||||
base64_sem1 = example.Program('base64_sem1', 'base64_sem1.c')
|
||||
base64_sem2 = example.Program('base64_sem2', 'base64_sem2.c')
|
||||
env.Alias("examples", [dns, base64, base64_sem1, base64_sem2])
|
||||
18
src/bindings/php/README.md
Normal file
18
src/bindings/php/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Building
|
||||
========
|
||||
Requirements:
|
||||
* SWIG 2.0
|
||||
* A properly configured [phpenv](https://github.com/CHH/phpenv)
|
||||
|
||||
SCons finds your PHP include path from `php-config`, so if you don't have that working, you're going to have a bad time.
|
||||
|
||||
If you want to run the tests, you will also need to install PHPUnit. Do this with pyrus and save yourself some hell.
|
||||
|
||||
pyrus channel-discover pear.phpunit.de
|
||||
pyrus channel-discover pear.symfony.com
|
||||
pyrus channel-discover pear.symfony-project.com
|
||||
pyrus install --optionaldeps phpunit/PHPUnit
|
||||
|
||||
Installing
|
||||
==========
|
||||
We're not building a proper package yet, but you can copy `build/$VARIANT/src/bindings/php/hammer.so` to your PHP extension directory (`scons test` will do this for you if you're using phpenv; for a system-wide php you'll probably have to use sudo) and add "extension=hammer.so" to your php.ini. There is a "hammer.ini" in src/bindings/php for your convenience; you can put it in the `conf.d` directory where PHP expects to find its configuration. `scons test` will do this for you too. You'll also need to point your include_path to the location of hammer.php, which will be `build/$VARIANT/src/bindings/php/hammer.php` until you put it somewhere else.
|
||||
31
src/bindings/php/SConscript
Normal file
31
src/bindings/php/SConscript
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# -*- python -*-
|
||||
import os, os.path
|
||||
Import('env libhammer_shared testruns')
|
||||
|
||||
phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0)
|
||||
|
||||
php_include = os.popen("php-config --include-dir").read().rstrip()
|
||||
phpenv.Append(CPPPATH = ['../../', php_include, os.path.join(php_include, 'main'), os.path.join(php_include, 'Zend'), os.path.join(php_include, 'TSRM')])
|
||||
phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error'])
|
||||
phpenv.Append(LIBS = ['hammer'])
|
||||
phpenv.Append(LIBPATH = ['../../'])
|
||||
|
||||
swig = ['hammer.i']
|
||||
bindings_src = phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], swig, 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE')
|
||||
libhammer_php = phpenv.SharedLibrary('hammer', ['hammer_wrap.c'])
|
||||
Default(swig, bindings_src, libhammer_php)
|
||||
|
||||
phptestenv = phpenv.Clone()
|
||||
phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0]))
|
||||
phptests = ('Tests')
|
||||
phpextprefix = os.popen("php-config --extension-dir").read().rstrip()
|
||||
phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_php, Copy("$TARGET", "$SOURCE"))
|
||||
AlwaysBuild(phplib)
|
||||
phpprefix = os.popen("php-config --prefix").read().rstrip()
|
||||
phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE"))
|
||||
phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests")
|
||||
phptest = Alias("testphp", [phptestexec], phptestexec)
|
||||
AlwaysBuild(phptest)
|
||||
testruns.append(phptest)
|
||||
|
||||
|
||||
40
src/bindings/php/Tests/ActionTest.php
Normal file
40
src/bindings/php/Tests/ActionTest.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
function actTest($token)
|
||||
{
|
||||
if (is_array($token) === true) {
|
||||
foreach($token as $chr) {
|
||||
$ret[] = strtoupper($chr);
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
return strtoupper($token);
|
||||
}
|
||||
}
|
||||
|
||||
class ActionTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_action(hammer_sequence(hammer_choice(hammer_ch("a"), hammer_ch("A")), hammer_choice(hammer_ch("b"), hammer_ch("B"))), "actTest");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "ab");
|
||||
$result2 = hammer_parse($this->parser, "AB");
|
||||
$result3 = hammer_parse($this->parser, "aB");
|
||||
$this->assertEquals(["A", "B"], $result1);
|
||||
$this->assertEquals(["A", "B"], $result2);
|
||||
$this->assertEquals(["A", "B"], $result3);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "XX");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
35
src/bindings/php/Tests/AndTest.php
Normal file
35
src/bindings/php/Tests/AndTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class AndTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser1;
|
||||
protected $parser2;
|
||||
protected $parser3;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser1 = hammer_sequence(hammer_and(hammer_ch("0")), hammer_ch("0"));
|
||||
$this->parser2 = hammer_sequence(hammer_and(hammer_ch("0")), hammer_ch("1"));
|
||||
$this->parser3 = hammer_sequence(hammer_ch("1"), hammer_and(hammer_ch("2")));
|
||||
}
|
||||
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "0");
|
||||
$this->assertEquals(array("0"), $result);
|
||||
}
|
||||
|
||||
public function testFailure2()
|
||||
{
|
||||
$result = hammer_parse($this->parser2, "0");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
|
||||
public function testSuccess3()
|
||||
{
|
||||
$result = hammer_parse($this->parser3, "12");
|
||||
$this->assertEquals(array("1"), $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
35
src/bindings/php/Tests/ButNotTest.php
Normal file
35
src/bindings/php/Tests/ButNotTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class ButNotTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser1;
|
||||
protected $parser2;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser1 = hammer_butnot(hammer_ch("a"), hammer_token("ab"));
|
||||
$this->parser2 = hammer_butnot(hammer_ch_range('0', '9'), hammer_ch('6'));
|
||||
}
|
||||
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser1, "a");
|
||||
$result2 = hammer_parse($this->parser1, "aa");
|
||||
$this->assertEquals("a", $result1);
|
||||
$this->assertEquals("a", $result1);
|
||||
}
|
||||
|
||||
public function testFailure1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "ab");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
|
||||
public function testFailure2()
|
||||
{
|
||||
$result = hammer_parse($this->parser2, "6");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/ChRangeTest.php
Normal file
24
src/bindings/php/Tests/ChRangeTest.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class ChRangeTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_ch_range("a", "c");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "b");
|
||||
$this->assertEquals("b", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "d");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/ChTest.php
Normal file
24
src/bindings/php/Tests/ChTest.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class ChTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_ch("\xa2");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xa2");
|
||||
$this->assertEquals("\xa2", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "95");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
27
src/bindings/php/Tests/ChoiceTest.php
Normal file
27
src/bindings/php/Tests/ChoiceTest.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class ChoiceTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_choice(hammer_ch("a"), hammer_ch("b"));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "a");
|
||||
$result2 = hammer_parse($this->parser, "b");
|
||||
$this->assertEquals("a", $result1);
|
||||
$this->assertEquals("b", $result2);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "c");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
25
src/bindings/php/Tests/DifferenceTest.php
Normal file
25
src/bindings/php/Tests/DifferenceTest.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class DifferenceTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_difference(hammer_token("ab"), hammer_ch("a"));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "ab");
|
||||
$this->assertEquals("ab", $result);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "a");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/EndTest.php
Normal file
24
src/bindings/php/Tests/EndTest.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class EndPTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_sequence(hammer_ch("a"), hammer_end());
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "a");
|
||||
$this->assertEquals(array("a"), $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "aa");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
35
src/bindings/php/Tests/EpsilonPTest.php
Normal file
35
src/bindings/php/Tests/EpsilonPTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class EpsilonPTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser1;
|
||||
protected $parser2;
|
||||
protected $parser3;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser1 = hammer_sequence(hammer_ch("a"), hammer_epsilon(), hammer_ch("b"));
|
||||
$this->parser2 = hammer_sequence(hammer_epsilon(), hammer_ch("a"));
|
||||
$this->parser3 = hammer_sequence(hammer_ch("a"), hammer_epsilon());
|
||||
}
|
||||
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "ab");
|
||||
$this->assertEquals(array("a", "b"), $result);
|
||||
}
|
||||
|
||||
public function testSuccess2()
|
||||
{
|
||||
$result = hammer_parse($this->parser2, "a");
|
||||
$this->assertEquals(array("a"), $result);
|
||||
}
|
||||
|
||||
public function testSuccess3()
|
||||
{
|
||||
$result = hammer_parse($this->parser3, "ab");
|
||||
$this->assertEquals(array("a"), $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
25
src/bindings/php/Tests/IgnoreTest.php
Normal file
25
src/bindings/php/Tests/IgnoreTest.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class IgnoreTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_sequence(hammer_ch("a"), hammer_ignore(hammer_ch("b")), hammer_ch("c"));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "abc");
|
||||
$this->assertEquals(array("a", "c"), $result);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "ac");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
23
src/bindings/php/Tests/InTest.php
Normal file
23
src/bindings/php/Tests/InTest.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class InTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_in("abc");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "b");
|
||||
$this->assertEquals("b", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "d");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
30
src/bindings/php/Tests/Int16Test.php
Normal file
30
src/bindings/php/Tests/Int16Test.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Int16Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_int16();
|
||||
}
|
||||
public function testNegative()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xfe\x00");
|
||||
$this->assertEquals(-0x200, $result);
|
||||
}
|
||||
public function testPositive() {
|
||||
$result = hammer_parse($this->parser, "\x02\x00");
|
||||
$this->assertEquals(0x200, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xfe");
|
||||
$this->assertEquals(NULL, $result);
|
||||
$result = hammer_parse($this->parser, "\x02");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
31
src/bindings/php/Tests/Int32Test.php
Normal file
31
src/bindings/php/Tests/Int32Test.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Int32Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_int32();
|
||||
}
|
||||
public function testNegative()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xff\xfe\x00\x00");
|
||||
$this->assertEquals(-0x20000, $result);
|
||||
}
|
||||
public function testPositive()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x00\x02\x00\x00");
|
||||
$this->assertEquals(0x20000, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xff\xfe\x00");
|
||||
$this->assertEquals(NULL, $result);
|
||||
$result = hammer_parse($this->parser, "\x00\x02\x00");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/Int64Test.php
Normal file
24
src/bindings/php/Tests/Int64Test.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Int64Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_int64();
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00\x00");
|
||||
$this->assertEquals(-0x200000000, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/Int8Test.php
Normal file
24
src/bindings/php/Tests/Int8Test.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Int8Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_int8();
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x88");
|
||||
$this->assertEquals(-0x78, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
23
src/bindings/php/Tests/IntRangeTest.php
Normal file
23
src/bindings/php/Tests/IntRangeTest.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class IntRangeTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_int_range(hammer_uint8(), 3, 10);
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x05");
|
||||
$this->assertEquals(5, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\xb");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
27
src/bindings/php/Tests/LeftTest.php
Normal file
27
src/bindings/php/Tests/LeftTest.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class LeftTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_left(hammer_ch("a"), hammer_ch(" "));
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "a ");
|
||||
$this->assertEquals("a", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "a");
|
||||
$result2 = hammer_parse($this->parser, " ");
|
||||
$result3 = hammer_parse($this->parser, "ab");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
$this->assertEquals(NULL, $result3);
|
||||
}
|
||||
}
|
||||
?>
|
||||
36
src/bindings/php/Tests/LeftrecTest.php
Normal file
36
src/bindings/php/Tests/LeftrecTest.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class LeftrecTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_indirect();
|
||||
hammer_bind_indirect($this->parser, hammer_choice(hammer_sequence($this->parser, hammer_ch("a")), hammer_ch("a")));
|
||||
}
|
||||
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "a");
|
||||
$this->assertEquals("a", $result);
|
||||
}
|
||||
/* These don't work in the underlying C so they won't work here either */
|
||||
/*
|
||||
public function testSuccess2()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "aa");
|
||||
var_dump($result);
|
||||
$this->assertEquals(array("a", "a"), $result);
|
||||
}
|
||||
|
||||
public function testSuccess3()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "aaa");
|
||||
var_dump($result);
|
||||
$this->assertEquals(array(array("a", "a"), "a"), $result);
|
||||
}
|
||||
*/
|
||||
}
|
||||
?>
|
||||
31
src/bindings/php/Tests/Many1Test.php
Normal file
31
src/bindings/php/Tests/Many1Test.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Many1Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_many1(hammer_choice(hammer_ch("a"), hammer_ch("b")));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "a");
|
||||
$result2 = hammer_parse($this->parser, "b");
|
||||
$result3 = hammer_parse($this->parser, "aabbaba");
|
||||
$this->assertEquals(array("a"), $result1);
|
||||
$this->assertEquals(array("b"), $result2);
|
||||
$this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result3);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "");
|
||||
$result2 = hammer_parse($this->parser, "daabbabadef");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
}
|
||||
}
|
||||
?>
|
||||
25
src/bindings/php/Tests/ManyTest.php
Normal file
25
src/bindings/php/Tests/ManyTest.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class ManyTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_many(hammer_choice(hammer_ch("a"), hammer_ch("b")));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "");
|
||||
$result2 = hammer_parse($this->parser, "a");
|
||||
$result3 = hammer_parse($this->parser, "b");
|
||||
$result4 = hammer_parse($this->parser, "aabbaba");
|
||||
$this->assertEquals(array(), $result1);
|
||||
$this->assertEquals(array("a"), $result2);
|
||||
$this->assertEquals(array("b"), $result3);
|
||||
$this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result4);
|
||||
}
|
||||
}
|
||||
?>
|
||||
35
src/bindings/php/Tests/MiddleTest.php
Normal file
35
src/bindings/php/Tests/MiddleTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class MiddleTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_middle(hammer_ch(" "), hammer_ch("a"), hammer_ch(" "));
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, " a ");
|
||||
$this->assertEquals("a", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "a");
|
||||
$result2 = hammer_parse($this->parser, " ");
|
||||
$result3 = hammer_parse($this->parser, " a");
|
||||
$result4 = hammer_parse($this->parser, "a ");
|
||||
$result5 = hammer_parse($this->parser, " b ");
|
||||
$result6 = hammer_parse($this->parser, "ba ");
|
||||
$result7 = hammer_parse($this->parser, " ab");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
$this->assertEquals(NULL, $result3);
|
||||
$this->assertEquals(NULL, $result4);
|
||||
$this->assertEquals(NULL, $result5);
|
||||
$this->assertEquals(NULL, $result6);
|
||||
$this->assertEquals(NULL, $result7);
|
||||
}
|
||||
}
|
||||
?>
|
||||
23
src/bindings/php/Tests/NotInTest.php
Normal file
23
src/bindings/php/Tests/NotInTest.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class NotInTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_not_in("abc");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "d");
|
||||
$this->assertEquals("d", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "b");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
35
src/bindings/php/Tests/NotTest.php
Normal file
35
src/bindings/php/Tests/NotTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class NotTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser1;
|
||||
protected $parser2;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser1 = hammer_sequence(hammer_ch("a"), hammer_choice(hammer_ch("+"), hammer_token("++")), hammer_ch("b"));
|
||||
$this->parser2 = hammer_sequence(hammer_ch("a"), hammer_choice(hammer_sequence(hammer_ch("+"), hammer_not(hammer_ch("+"))), hammer_token("++")), hammer_ch("b"));
|
||||
}
|
||||
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "a+b");
|
||||
$this->assertEquals(array("a", "+", "b"), $result);
|
||||
}
|
||||
|
||||
public function testFailure1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "a++b");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
|
||||
public function testSuccess2()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser2, "a+b");
|
||||
$result2 = hammer_parse($this->parser2, "a++b");
|
||||
$this->assertEquals(array("a", array("+"), "b"), $result1);
|
||||
$this->assertEquals(array("a", "++", "b"), $result2);
|
||||
}
|
||||
}
|
||||
?>
|
||||
19
src/bindings/php/Tests/NothingTest.php
Normal file
19
src/bindings/php/Tests/NothingTest.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class NothingPTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_nothing();
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "a");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
33
src/bindings/php/Tests/OptionalTest.php
Normal file
33
src/bindings/php/Tests/OptionalTest.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class OptionalTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_sequence(hammer_ch("a"), hammer_optional(hammer_choice(hammer_ch("b"), hammer_ch("c"))), hammer_ch("d"));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "abd");
|
||||
$result2 = hammer_parse($this->parser, "acd");
|
||||
$result3 = hammer_parse($this->parser, "ad");
|
||||
$this->assertEquals(array("a", "b", "d"), $result1);
|
||||
$this->assertEquals(array("a", "c", "d"), $result2);
|
||||
$this->assertEquals(array("a", NULL, "d"), $result3);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "aed");
|
||||
$result2 = hammer_parse($this->parser, "ab");
|
||||
$result3 = hammer_parse($this->parser, "ac");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
$this->assertEquals(NULL, $result3);
|
||||
}
|
||||
}
|
||||
?>
|
||||
31
src/bindings/php/Tests/PredicateTest.php
Normal file
31
src/bindings/php/Tests/PredicateTest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
function predTest($token)
|
||||
{
|
||||
return ($token[0] === $token[1]);
|
||||
}
|
||||
|
||||
class PredicateTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_predicate(hammer_many1(hammer_choice(hammer_ch('a'), hammer_ch('b'))), "predTest");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "aa");
|
||||
$result2 = hammer_parse($this->parser, "bb");
|
||||
$this->assertEquals(["a", "a"], $result1);
|
||||
$this->assertEquals(["b", "b"], $result2);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "ab");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
27
src/bindings/php/Tests/RepeatNTest.php
Normal file
27
src/bindings/php/Tests/RepeatNTest.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class RepeatNTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_repeat_n(hammer_choice(hammer_ch("a"), hammer_ch("b")), 2);
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "abdef");
|
||||
$this->assertEquals(array("a", "b"), $result);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "adef");
|
||||
$result2 = hammer_parse($this->parser, "dabdef");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
}
|
||||
}
|
||||
?>
|
||||
27
src/bindings/php/Tests/RightTest.php
Normal file
27
src/bindings/php/Tests/RightTest.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class RightTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_right(hammer_ch(" "), hammer_ch("a"));
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, " a");
|
||||
$this->assertEquals("a", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "a");
|
||||
$result2 = hammer_parse($this->parser, " ");
|
||||
$result3 = hammer_parse($this->parser, "ba");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
$this->assertEquals(NULL, $result3);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/RightrecTest.php
Normal file
24
src/bindings/php/Tests/RightrecTest.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class RightrecTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_indirect();
|
||||
hammer_bind_indirect($this->parser, hammer_choice(hammer_sequence(hammer_ch("a"), $this->parser), hammer_epsilon()));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "a");
|
||||
$result2 = hammer_parse($this->parser, "aa");
|
||||
$result3 = hammer_parse($this->parser, "aaa");
|
||||
$this->assertEquals(array("a"), $result1);
|
||||
$this->assertEquals(array("a", array("a")), $result2);
|
||||
$this->assertEquals(array("a", array("a", array("a"))), $result3);
|
||||
}
|
||||
}
|
||||
?>
|
||||
31
src/bindings/php/Tests/SepBy1Test.php
Normal file
31
src/bindings/php/Tests/SepBy1Test.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class SepBy1Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_sep_by1(hammer_choice(hammer_ch("1"), hammer_ch("2"), hammer_ch("3")), hammer_ch(","));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "1,2,3");
|
||||
$result2 = hammer_parse($this->parser, "1,3,2");
|
||||
$result3 = hammer_parse($this->parser, "1,3");
|
||||
$result4 = hammer_parse($this->parser, "3");
|
||||
$this->assertEquals(array("1", "2", "3"), $result1);
|
||||
$this->assertEquals(array("1", "3", "2"), $result2);
|
||||
$this->assertEquals(array("1", "3"), $result3);
|
||||
$this->assertEquals(array("3"), $result4);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
27
src/bindings/php/Tests/SepByTest.php
Normal file
27
src/bindings/php/Tests/SepByTest.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class SepByTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_sep_by(hammer_choice(hammer_ch("1"), hammer_ch("2"), hammer_ch("3")), hammer_ch(","));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "1,2,3");
|
||||
$result2 = hammer_parse($this->parser, "1,3,2");
|
||||
$result3 = hammer_parse($this->parser, "1,3");
|
||||
$result4 = hammer_parse($this->parser, "3");
|
||||
$result5 = hammer_parse($this->parser, "");
|
||||
$this->assertEquals(array("1", "2", "3"), $result1);
|
||||
$this->assertEquals(array("1", "3", "2"), $result2);
|
||||
$this->assertEquals(array("1", "3"), $result3);
|
||||
$this->assertEquals(array("3"), $result4);
|
||||
$this->assertEquals(array(), $result5);
|
||||
}
|
||||
}
|
||||
?>
|
||||
39
src/bindings/php/Tests/SequenceTest.php
Normal file
39
src/bindings/php/Tests/SequenceTest.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class SequenceTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser1;
|
||||
protected $parser2;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser1 = hammer_sequence(hammer_ch("a"), hammer_ch("b"));
|
||||
$this->parser2 = hammer_sequence(hammer_ch("a"), hammer_whitespace(hammer_ch("b")));
|
||||
}
|
||||
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "ab");
|
||||
$this->assertEquals(array("a", "b"), $result);
|
||||
}
|
||||
|
||||
public function testFailure1()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser1, "a");
|
||||
$result2 = hammer_parse($this->parser2, "b");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
}
|
||||
|
||||
public function testSuccess2()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser2, "ab");
|
||||
$result2 = hammer_parse($this->parser2, "a b");
|
||||
$result3 = hammer_parse($this->parser2, "a b");
|
||||
$this->assertEquals(array("a", "b"), $result1);
|
||||
$this->assertEquals(array("a", "b"), $result2);
|
||||
$this->assertEquals(array("a", "b"), $result3);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/TokenTest.php
Normal file
24
src/bindings/php/Tests/TokenTest.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class TokenTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_token("95\xa2");
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "95\xa2");
|
||||
$this->assertEquals("95\xa2", $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "95");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/Uint16Test.php
Normal file
24
src/bindings/php/Tests/Uint16Test.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Uint16Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_uint16();
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x02\x00");
|
||||
$this->assertEquals(0x200, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x02");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/Uint32Test.php
Normal file
24
src/bindings/php/Tests/Uint32Test.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Uint32Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_uint32();
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x00\x02\x00\x00");
|
||||
$this->assertEquals(0x20000, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x00\x02\x00");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/Uint64Test.php
Normal file
24
src/bindings/php/Tests/Uint64Test.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Uint64Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_uint64();
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00\x00");
|
||||
$this->assertEquals(0x200000000, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
src/bindings/php/Tests/Uint8Test.php
Normal file
24
src/bindings/php/Tests/Uint8Test.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
include_once 'hammer.php';
|
||||
|
||||
class Uint8Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_uint8();
|
||||
}
|
||||
public function testSuccess()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "\x78");
|
||||
$this->assertEquals(0x78, $result);
|
||||
}
|
||||
public function testFailure()
|
||||
{
|
||||
$result = hammer_parse($this->parser, "");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
43
src/bindings/php/Tests/WhitespaceTest.php
Normal file
43
src/bindings/php/Tests/WhitespaceTest.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class WhitespaceTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser1;
|
||||
protected $parser2;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser1 = hammer_whitespace(hammer_ch("a"));
|
||||
$this->parser2 = hammer_whitespace(hammer_end());
|
||||
}
|
||||
public function testSuccess1()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser1, "a");
|
||||
$result2 = hammer_parse($this->parser1, " a");
|
||||
$result3 = hammer_parse($this->parser1, " a");
|
||||
$result4 = hammer_parse($this->parser1, "\ta");
|
||||
$this->assertEquals("a", $result1);
|
||||
$this->assertEquals("a", $result2);
|
||||
$this->assertEquals("a", $result3);
|
||||
$this->assertEquals("a", $result4);
|
||||
}
|
||||
public function testFailure1()
|
||||
{
|
||||
$result = hammer_parse($this->parser1, "_a");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
public function testSuccess2()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser2, "");
|
||||
$result2 = hammer_parse($this->parser2, " ");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
}
|
||||
public function testFailure2()
|
||||
{
|
||||
$result = hammer_parse($this->parser2, " x");
|
||||
$this->assertEquals(NULL, $result);
|
||||
}
|
||||
}
|
||||
?>
|
||||
29
src/bindings/php/Tests/XorTest.php
Normal file
29
src/bindings/php/Tests/XorTest.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
include_once 'hammer.php';
|
||||
|
||||
class XorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->parser = hammer_xor(hammer_ch_range("0", "6"), hammer_ch_range("5", "9"));
|
||||
}
|
||||
|
||||
public function testSuccess()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "0");
|
||||
$result2 = hammer_parse($this->parser, "9");
|
||||
$this->assertEquals("0", $result1);
|
||||
$this->assertEquals("9", $result2);
|
||||
}
|
||||
|
||||
public function testFailure()
|
||||
{
|
||||
$result1 = hammer_parse($this->parser, "5");
|
||||
$result2 = hammer_parse($this->parser, "a");
|
||||
$this->assertEquals(NULL, $result1);
|
||||
$this->assertEquals(NULL, $result2);
|
||||
}
|
||||
}
|
||||
?>
|
||||
255
src/bindings/php/hammer.i
Normal file
255
src/bindings/php/hammer.i
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
%module hammer;
|
||||
%include "exception.i";
|
||||
%{
|
||||
#include "allocator.h"
|
||||
%}
|
||||
|
||||
%ignore HCountedArray_;
|
||||
|
||||
%inline %{
|
||||
static int h_tt_php;
|
||||
%}
|
||||
|
||||
%init %{
|
||||
h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php");
|
||||
%}
|
||||
|
||||
%inline {
|
||||
struct HParsedToken_;
|
||||
struct HParseResult_;
|
||||
void hpt_to_php(const struct HParsedToken_ *token, zval *return_value);
|
||||
|
||||
static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data);
|
||||
}
|
||||
|
||||
%typemap(in) (const uint8_t* str, const size_t len) {
|
||||
$1 = (uint8_t*)(*$input)->value.str.val;
|
||||
$2 = (*$input)->value.str.len;
|
||||
}
|
||||
|
||||
%apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) }
|
||||
%apply (const uint8_t* str, const size_t len) { (const uint8_t* charset, size_t length) }
|
||||
|
||||
%typemap(in) void*[] {
|
||||
if (IS_ARRAY == Z_TYPE_PP($input)) {
|
||||
HashTable *arr = Z_ARRVAL_PP($input);
|
||||
HashPosition pointer;
|
||||
int size = zend_hash_num_elements(arr);
|
||||
int i = 0;
|
||||
int res = 0;
|
||||
$1 = (void**)malloc((size+1)*sizeof(HParser*));
|
||||
for (i=0; i<size; i++) {
|
||||
zval **data;
|
||||
if (zend_hash_index_find(arr, i, (void**)&data) == FAILURE) {
|
||||
$1 = NULL;
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "index in parser array out of bounds", 0 TSRMLS_CC);
|
||||
} else {
|
||||
res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "that wasn't an HParser", 0 TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$1 = NULL;
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "that wasn't an array of HParsers", 0 TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(in) uint8_t {
|
||||
if (IS_LONG == Z_TYPE_PP($input)) {
|
||||
$1 = Z_LVAL_PP($input);
|
||||
} else if (IS_STRING != Z_TYPE_PP($input)) {
|
||||
// FIXME raise some error
|
||||
} else {
|
||||
$1 = *(uint8_t*)Z_STRVAL_PP($input);
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(out) HBytes* {
|
||||
RETVAL_STRINGL((char*)$1->token, $1->len, 1);
|
||||
}
|
||||
|
||||
%typemap(out) struct HParseResult_* {
|
||||
if ($1 == NULL) {
|
||||
/* If we want parse errors to be exceptions, this is the place to do it */
|
||||
//SWIG_exception(SWIG_TypeError, "typemap: should have been an HParseResult*, was NULL");
|
||||
RETVAL_NULL();
|
||||
} else {
|
||||
hpt_to_php($1->ast, $result);
|
||||
}
|
||||
}
|
||||
|
||||
%rename("hammer_token") h_token;
|
||||
%rename("hammer_int_range") h_int_range;
|
||||
%rename("hammer_bits") h_bits;
|
||||
%rename("hammer_int64") h_int64;
|
||||
%rename("hammer_int32") h_int32;
|
||||
%rename("hammer_int16") h_int16;
|
||||
%rename("hammer_int8") h_int8;
|
||||
%rename("hammer_uint64") h_uint64;
|
||||
%rename("hammer_uint32") h_uint32;
|
||||
%rename("hammer_uint16") h_uint16;
|
||||
%rename("hammer_uint8") h_uint8;
|
||||
%rename("hammer_whitespace") h_whitespace;
|
||||
%rename("hammer_left") h_left;
|
||||
%rename("hammer_right") h_right;
|
||||
%rename("hammer_middle") h_middle;
|
||||
%rename("hammer_end") h_end_p;
|
||||
%rename("hammer_nothing") h_nothing_p;
|
||||
%rename("hammer_butnot") h_butnot;
|
||||
%rename("hammer_difference") h_difference;
|
||||
%rename("hammer_xor") h_xor;
|
||||
%rename("hammer_many") h_many;
|
||||
%rename("hammer_many1") h_many1;
|
||||
%rename("hammer_repeat_n") h_repeat_n;
|
||||
%rename("hammer_optional") h_optional;
|
||||
%rename("hammer_ignore") h_ignore;
|
||||
%rename("hammer_sep_by") h_sepBy;
|
||||
%rename("hammer_sep_by1") h_sepBy1;
|
||||
%rename("hammer_epsilon") h_epsilon_p;
|
||||
%rename("hammer_length_value") h_length_value;
|
||||
%rename("hammer_and") h_and;
|
||||
%rename("hammer_not") h_not;
|
||||
%rename("hammer_indirect") h_indirect;
|
||||
%rename("hammer_bind_indirect") h_bind_indirect;
|
||||
%rename("hammer_compile") h_compile;
|
||||
%rename("hammer_parse") h_parse;
|
||||
|
||||
%include "../swig/hammer.i";
|
||||
|
||||
%inline {
|
||||
void hpt_to_php(const HParsedToken *token, zval *return_value) {
|
||||
TSRMLS_FETCH();
|
||||
if (!token) {
|
||||
RETVAL_NULL();
|
||||
return;
|
||||
}
|
||||
switch (token->token_type) {
|
||||
case TT_NONE:
|
||||
RETVAL_NULL();
|
||||
break;
|
||||
case TT_BYTES:
|
||||
RETVAL_STRINGL((char*)token->token_data.bytes.token, token->token_data.bytes.len, 1);
|
||||
break;
|
||||
case TT_SINT:
|
||||
RETVAL_LONG(token->token_data.sint);
|
||||
break;
|
||||
case TT_UINT:
|
||||
RETVAL_LONG(token->token_data.uint);
|
||||
break;
|
||||
case TT_SEQUENCE:
|
||||
array_init(return_value);
|
||||
for (int i=0; i < token->token_data.seq->used; i++) {
|
||||
zval *tmp;
|
||||
ALLOC_INIT_ZVAL(tmp);
|
||||
hpt_to_php(token->token_data.seq->elements[i], tmp);
|
||||
add_next_index_zval(return_value, tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (token->token_type == h_tt_php) {
|
||||
zval *tmp;
|
||||
tmp = (zval*)token->token_data.user;
|
||||
RETVAL_ZVAL(tmp, 0, 0);
|
||||
} else {
|
||||
int res = 0;
|
||||
res = SWIG_ConvertPtr(return_value, (void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "hpt_to_php: that wasn't an HParsedToken", 0 TSRMLS_CC);
|
||||
}
|
||||
// TODO: support registry
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static HParsedToken* call_action(const HParseResult *p, void *user_data) {
|
||||
zval **args;
|
||||
zval func;
|
||||
zval *ret;
|
||||
TSRMLS_FETCH();
|
||||
args = (zval**)h_arena_malloc(p->arena, sizeof(*args) * 1); // one-element array of pointers
|
||||
MAKE_STD_ZVAL(args[0]);
|
||||
ALLOC_INIT_ZVAL(ret);
|
||||
ZVAL_STRING(&func, (const char*)user_data, 0);
|
||||
hpt_to_php(p->ast, args[0]);
|
||||
int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC);
|
||||
if (ok != SUCCESS) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "call_action failed", 0 TSRMLS_CC);
|
||||
return NULL;
|
||||
}
|
||||
// Whatever the zval is, stuff it into a token
|
||||
HParsedToken *tok = h_make(p->arena, h_tt_php, ret);
|
||||
return tok;
|
||||
}
|
||||
|
||||
static int call_predicate(HParseResult *p, void *user_data) {
|
||||
zval **args;
|
||||
zval func;
|
||||
zval *ret;
|
||||
TSRMLS_FETCH();
|
||||
args = (zval**)h_arena_malloc(p->arena, sizeof(*args) * 1); // one-element array of pointers
|
||||
MAKE_STD_ZVAL(args[0]);
|
||||
ALLOC_INIT_ZVAL(ret);
|
||||
ZVAL_STRING(&func, (const char*)user_data, 0);
|
||||
hpt_to_php(p->ast, args[0]);
|
||||
int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC);
|
||||
if (ok != SUCCESS) {
|
||||
zend_throw_exception(zend_exception_get_default(TSRMLS_C), "call_predicate failed", 0 TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
return Z_LVAL_P(ret);
|
||||
}
|
||||
|
||||
HParser* hammer_action(HParser *parser, const char *name) {
|
||||
const char *fname = strdup(name);
|
||||
return h_action(parser, call_action, (void*)fname);
|
||||
}
|
||||
|
||||
HParser* hammer_predicate(HParser *parser, const char *name) {
|
||||
const char *fname = strdup(name);
|
||||
return h_attr_bool(parser, call_predicate, (void*)fname);
|
||||
}
|
||||
}
|
||||
|
||||
%pragma(php) code="
|
||||
|
||||
function hammer_ch($ch)
|
||||
{
|
||||
if (is_string($ch))
|
||||
return hammer_token($ch);
|
||||
else
|
||||
return h_ch($ch);
|
||||
}
|
||||
|
||||
function hammer_choice()
|
||||
{
|
||||
$arg_list = func_get_args();
|
||||
$arg_list[] = NULL;
|
||||
return h_choice__a($arg_list);
|
||||
}
|
||||
|
||||
function hammer_sequence()
|
||||
{
|
||||
$arg_list = func_get_args();
|
||||
$arg_list[] = NULL;
|
||||
return h_sequence__a($arg_list);
|
||||
}
|
||||
|
||||
function hammer_ch_range($low, $high)
|
||||
{
|
||||
return hammer_action(h_ch_range($low, $high), \"chr\");
|
||||
}
|
||||
|
||||
function hammer_in($charset)
|
||||
{
|
||||
return hammer_action(h_in($charset), \"chr\");
|
||||
}
|
||||
|
||||
function hammer_not_in($charset)
|
||||
{
|
||||
return hammer_action(h_not_in($charset), \"chr\");
|
||||
}
|
||||
"
|
||||
|
||||
2
src/bindings/php/hammer.ini
Normal file
2
src/bindings/php/hammer.ini
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
enable_dl = On
|
||||
extension = "hammer.so"
|
||||
|
|
@ -344,3 +344,5 @@ def int64(): return _h_int64()
|
|||
%}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue