Skip to content

Commit

Permalink
the Great Merge continues
Browse files Browse the repository at this point in the history
  • Loading branch information
abiggerhammer committed Oct 8, 2019
2 parents 27f3873 + 72146e1 commit 1bd778f
Show file tree
Hide file tree
Showing 25 changed files with 683 additions and 241 deletions.
7 changes: 4 additions & 3 deletions README.md
Expand Up @@ -35,8 +35,9 @@ Installing
* pkg-config (for `scons test`)
* glib-2.0 (>= 2.29) (for `scons test`)
* glib-2.0-dev (for `scons test`)
* [swig](http://swig.org/) (for Python/Perl/PHP bindings; Perl requires >= 2.0.8)
* python2.7-dev (for Python bindings)
* [swig](http://swig.org/) (for Python/Perl/PHP bindings; Perl requires >= 2.0.8; Python 3.x requires >= 3.0.0)
* python2.7-dev (for Python 2 bindings)
* python3-dev (>= 3.5) (for Python 3 bindings)
* a JDK (for Java bindings)
* a working [phpenv](https://github.com/CHH/phpenv) configuration (for PHP bindings)
* [Ruby](https://www.ruby-lang.org/) >= 1.9.3 and bundler, for the Ruby bindings
Expand Down Expand Up @@ -73,7 +74,7 @@ The `examples/` directory contains some simple examples, currently including:

Known Issues
============
The Python bindings only work with Python 2.7. SCons doesn't work with Python 3, and PyCapsule isn't available in 2.6 and below, so 2.7 is all you get. Sorry about that.
The Python bindings work with Python 2.7, and Python 3.5+.

The requirement for SWIG >= 2.0.8 for Perl bindings is due to a [known bug](http://sourceforge.net/p/swig/patches/324/) in SWIG. [ppa:dns/irc](https://launchpad.net/~dns/+archive/irc) has backports of SWIG 2.0.8 for Ubuntu versions 10.04-12.10; you can also [build SWIG from source](http://www.swig.org/download.html).

Expand Down
10 changes: 7 additions & 3 deletions SConstruct
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os
import os.path
import platform
Expand All @@ -12,6 +15,7 @@ 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', ['cpp', 'dotnet', 'perl', 'php', 'python', 'ruby']))
vars.Add('python', 'Python interpreter', 'python')

tools = ['default', 'scanreplace']
if 'dotnet' in ARGUMENTS.get('bindings', []):
Expand Down Expand Up @@ -43,9 +47,9 @@ env['prefix'] = os.path.abspath(env['prefix'])
if 'DESTDIR' in env:
env['DESTDIR'] = os.path.abspath(env['DESTDIR'])
if rel_prefix:
print >>sys.stderr, '--!!-- You used a relative prefix with a DESTDIR. This is probably not what you'
print >>sys.stderr, '--!!-- you want; files will be installed in'
print >>sys.stderr, '--!!-- %s' % (calcInstallPath('$prefix'),)
print('--!!-- You used a relative prefix with a DESTDIR. This is probably not what you', file=sys.stderr)
print('--!!-- you want; files will be installed in', file=sys.stderr)
print('--!!-- %s' % (calcInstallPath('$prefix'),), file=sys.stderr)


env['libpath'] = calcInstallPath('$prefix', 'lib')
Expand Down
2 changes: 2 additions & 0 deletions examples/SConscript
@@ -1,3 +1,5 @@
from __future__ import absolute_import, division, print_function

Import('env')

example = env.Clone()
Expand Down
12 changes: 6 additions & 6 deletions examples/base64.py
Expand Up @@ -10,7 +10,7 @@
# base64_sem1.py and base64_sem2.py for examples how to attach appropriate
# semantic actions to the grammar.

from __future__ import print_function
from __future__ import absolute_import, division, print_function

import sys

Expand All @@ -23,13 +23,13 @@ def init_parser():
alpha = h.choice(h.ch_range(0x41, 0x5a), h.ch_range(0x61, 0x7a))

# AUX.
plus = h.ch('+')
slash = h.ch('/')
equals = h.ch('=')
plus = h.ch(b'+')
slash = h.ch(b'/')
equals = h.ch(b'=')

bsfdig = h.choice(alpha, digit, plus, slash)
bsfdig_4bit = h.in_('AEIMQUYcgkosw048')
bsfdig_2bit = h.in_('AQgw')
bsfdig_4bit = h.in_(b'AEIMQUYcgkosw048')
bsfdig_2bit = h.in_(b'AQgw')
base64_3 = h.repeat_n(bsfdig, 4)
base64_2 = h.sequence(bsfdig, bsfdig, bsfdig_4bit, equals)
base64_1 = h.sequence(bsfdig, bsfdig_2bit, equals, equals)
Expand Down
24 changes: 12 additions & 12 deletions examples/base64_sem1.py
Expand Up @@ -13,7 +13,7 @@
# transform the parse tree in small steps in a bottom-up fashion. Compare
# base64_sem2.py for an alternative approach using a single top-level action.

from __future__ import print_function
from __future__ import absolute_import, division, print_function

import functools
import sys
Expand All @@ -26,17 +26,17 @@

def act_bsfdig(p, user_data=None):
# FIXME See the note in init_parser()
c = p if isinstance(p, (int, long)) else ord(p)
c = p if isinstance(p, h.INTEGER_TYPES) else ord(p)

if 0x41 <= c <= 0x5A: # A-Z
return c - 0x41
elif 0x61 <= c <= 0x7A: # a-z
return c - 0x61 + 26
elif 0x30 <= c <= 0x39: # 0-9
return c - 0x30 + 52
elif c == '+':
elif c == b'+':
return 62
elif c == '/':
elif c == b'/':
return 63
else:
raise ValueError
Expand Down Expand Up @@ -65,14 +65,14 @@ def act_base64_n(n, p, user_data=None):

x = 0
bits = 0
for i in xrange(0, n+1):
for i in range(0, n+1):
x <<= 6
x |= p[i] or 0
bits += 6

x >>= bits % 8 # align, i.e. cut off extra bits

for i in xrange(n):
for i in range(n):
item = x & 0xFF

res[n-1-i] = item # output the last byte and
Expand Down Expand Up @@ -118,16 +118,16 @@ def init_parser():
# literals, or integers
digit = h.ch_range(0x30, 0x39)
alpha = h.choice(h.ch_range(0x41, 0x5a), h.ch_range(0x61, 0x7a))
space = h.in_(" \t\n\r\f\v")
space = h.in_(b" \t\n\r\f\v")

# AUX.
plus = h.ch('+')
slash = h.ch('/')
equals = h.action(h.ch('='), act_equals)
plus = h.ch(b'+')
slash = h.ch(b'/')
equals = h.action(h.ch(b'='), act_equals)

bsfdig = h.action(h.choice(alpha, digit, plus, slash), act_bsfdig)
bsfdig_4bit = h.action(h.in_("AEIMQUYcgkosw048"), act_bsfdig_4bit)
bsfdig_2bit = h.action(h.in_("AQgw"), act_bsfdig_2bit)
bsfdig_4bit = h.action(h.in_(b"AEIMQUYcgkosw048"), act_bsfdig_4bit)
bsfdig_2bit = h.action(h.in_(b"AQgw"), act_bsfdig_2bit)
base64_3 = h.action(h.repeat_n(bsfdig, 4), act_base64_3)
base64_2 = h.action(h.sequence(bsfdig, bsfdig, bsfdig_4bit, equals),
act_base64_2)
Expand Down
20 changes: 10 additions & 10 deletions examples/base64_sem2.py
Expand Up @@ -14,7 +14,7 @@
# for an alternative approach using a fine-grained piece-by-piece
# transformation.

from __future__ import print_function
from __future__ import absolute_import, division, print_function

import functools
import sys
Expand All @@ -28,17 +28,17 @@
def bsfdig_value(p):
"""Return the numeric value of a parsed base64 digit.
"""
c = p if isinstance(p, (int, long)) else ord(p)
c = p if isinstance(p, h.INTEGER_TYPES) else ord(p)
if c:
if 0x41 <= c <= 0x5A: # A-Z
return c - 0x41
elif 0x61 <= c <= 0x7A: # a-z
return c - 0x61 + 26
elif 0x30 <= c <= 0x39: # 0-9
return c - 0x30 + 52
elif c == '+':
elif c == b'+':
return 62
elif c == '/':
elif c == b'/':
return 63
return 0

Expand Down Expand Up @@ -109,16 +109,16 @@ def init_parser():
# CORE
digit = h.ch_range(0x30, 0x39)
alpha = h.choice(h.ch_range(0x41, 0x5a), h.ch_range(0x61, 0x7a))
space = h.in_(" \t\n\r\f\v")
space = h.in_(b" \t\n\r\f\v")

# AUX.
plus = h.ch('+')
slash = h.ch('/')
equals = h.ch('=')
plus = h.ch(b'+')
slash = h.ch(b'/')
equals = h.ch(b'=')

bsfdig = h.choice(alpha, digit, plus, slash)
bsfdig_4bit = h.in_("AEIMQUYcgkosw048")
bsfdig_2bit = h.in_("AQgw")
bsfdig_4bit = h.in_(b"AEIMQUYcgkosw048")
bsfdig_2bit = h.in_(b"AQgw")
base64_3 = h.repeat_n(bsfdig, 4)
base64_2 = h.sequence(bsfdig, bsfdig, bsfdig_4bit, equals)
base64_1 = h.sequence(bsfdig, bsfdig_2bit, equals, equals)
Expand Down
9 changes: 7 additions & 2 deletions src/SConscript
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os.path

Import('env testruns')
Expand Down Expand Up @@ -66,7 +69,8 @@ misc_hammer_parts = [
'hammer.c',
'pprint.c',
'registry.c',
'system_allocator.c']
'system_allocator.c',
'sloballoc.c']

if env['PLATFORM'] == 'win32':
misc_hammer_parts += [
Expand All @@ -82,7 +86,8 @@ ctests = ['t_benchmark.c',
't_parser.c',
't_grammar.c',
't_misc.c',
't_regression.c']
't_mm.c',
't_regression.c']


static_library_name = 'hammer'
Expand Down
3 changes: 3 additions & 0 deletions src/bindings/cpp/SConscript
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os.path
Import("env libhammer_shared testruns targets")

Expand Down
3 changes: 3 additions & 0 deletions src/bindings/dotnet/SConscript
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os.path
Import("env libhammer_shared testruns targets")

Expand Down
3 changes: 3 additions & 0 deletions src/bindings/perl/SConscript
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os.path
Import("env libhammer_shared testruns targets")

Expand Down
3 changes: 3 additions & 0 deletions src/bindings/php/SConscript
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os, os.path
Import('env libhammer_shared testruns')

Expand Down
10 changes: 7 additions & 3 deletions src/bindings/python/SConscript
@@ -1,4 +1,7 @@
# -*- python -*-

from __future__ import absolute_import, division, print_function

import os, os.path
Import('env libhammer_shared testruns targets')

Expand All @@ -7,17 +10,18 @@ pythonenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0)
swig = pythonenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE"))
setup = ['setup.py']
pydir = os.path.join(env['BUILD_BASE'], 'src/bindings/python')
libhammer_python = pythonenv.Command(['hammer.py', 'hammer_wrap.c'], [swig, setup], 'python ' + os.path.join(pydir, 'setup.py') + ' build_ext --swig=swig3.0 --inplace')
pysetup = os.path.join(pydir, 'setup.py')
libhammer_python = pythonenv.Command(['hammer.py', 'hammer_wrap.c'], [swig, setup], '%s %s build_ext --inplace' % (env['python'], pysetup))
Default(libhammer_python)

pytestenv = pythonenv.Clone()
pytestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0]))
pytests = ['hammer_tests.py']
pytestexec = pytestenv.Command(['hammer.pyc', 'hammer_tests.pyc'], pytests + libhammer_python, "LD_LIBRARY_PATH=" + os.path.dirname(str(libhammer_shared[0])) + " nosetests -vv $SOURCE")
pytestexec = pytestenv.Command(['hammer.pyc', 'hammer_tests.pyc'], pytests + libhammer_python, "LD_LIBRARY_PATH=%s %s -mnose -vv $SOURCE" % (os.path.dirname(str(libhammer_shared[0])), env['python']))
pytest = Alias("testpython", [pytestexec], pytestexec)
AlwaysBuild(pytestexec)
testruns.append(pytest)

pyinstallexec = pythonenv.Command(None, libhammer_python, 'python ' + os.path.join(pydir, 'setup.py ') + ' install')
pyinstallexec = pythonenv.Command(None, libhammer_python, '%s %s install' % (env['python'], pysetup))
pyinstall = Alias("installpython", [pyinstallexec], pyinstallexec)
targets.append(pyinstall)

0 comments on commit 1bd778f

Please sign in to comment.