Skip to content

Instantly share code, notes, and snippets.

@zhuowei
Created January 1, 2015 02:46
Show Gist options
  • Save zhuowei/9e70c86bbb3ca5a1f283 to your computer and use it in GitHub Desktop.
Save zhuowei/9e70c86bbb3ca5a1f283 to your computer and use it in GitHub Desktop.
Python bindings for the Relooper library
"""
Wrapper for the Relooper api.
"""
"""
RELOOPERDLL_API void rl_set_output_buffer(char *buffer, int size);
RELOOPERDLL_API void rl_make_output_buffer(int size);
RELOOPERDLL_API void *rl_new_block(const char *text);
RELOOPERDLL_API void rl_delete_block(void *block);
RELOOPERDLL_API void rl_block_add_branch_to(void *from, void *to, const char *condition, const char *code);
RELOOPERDLL_API void *rl_new_relooper();
RELOOPERDLL_API void rl_delete_relooper(void *relooper);
RELOOPERDLL_API void rl_relooper_add_block(void *relooper, void *block);
RELOOPERDLL_API void rl_relooper_calculate(void *relooper, void *entry);
RELOOPERDLL_API void rl_relooper_render(void *relooper);
"""
import os
from ctypes import *
lib = cdll[os.path.dirname(__file__) + "/librelooper.so"]
class Relooper:
r"""
Basic usage:
>>> import relooper
>>> rl = relooper.Relooper()
>>> b1 = relooper.Block("Swag")
>>> rl.add_block(b1)
>>> rl.calculate(b1)
'Swag\n'
An example from test.cpp of the Relooper source, adapted for Python:
>>> import relooper
>>> b_a = relooper.Block("// block A\n")
>>> b_b = relooper.Block("// block B\n")
>>> b_c = relooper.Block("// block C\n")
>>> b_a.add_branch_to(b_b, "check == 10", "atob();")
>>> b_a.add_branch_to(b_c, None, "atoc();");
>>> b_b.add_branch_to(b_c, None, "btoc();");
>>> r = relooper.Relooper()
>>> r.add_block(b_a)
>>> r.add_block(b_b)
>>> r.add_block(b_c)
>>> print(r.calculate(b_a))
// block A
if (check == 10) {
atob();
// block B
btoc();
} else {
atoc();
}
// block C
<BLANKLINE>
"""
def __init__(self):
self.native_ptr = lib.rl_new_relooper();
def __del__(self):
lib.rl_delete_relooper(self.native_ptr)
def add_block(self, block):
lib.rl_relooper_add_block(self.native_ptr, block.native_ptr)
block.added = True
def calculate(self, entry):
lib.rl_relooper_calculate(self.native_ptr, entry.native_ptr)
mybuffer = create_string_buffer(0x10000)
lib.rl_set_output_buffer(mybuffer, len(mybuffer))
lib.rl_relooper_render(self.native_ptr)
return mybuffer.value.decode('utf-8')
class Block:
def __init__(self, text):
self.native_ptr = lib.rl_new_block(bytes(text, 'utf-8'))
def __del__(self):
if not self.added:
lib.rl_delete_block(self.native_ptr)
def add_branch_to(self, to_block, condition, code):
lib.rl_block_add_branch_to(self.native_ptr, to_block.native_ptr, bytes(condition, 'utf-8') if not condition is None else None,
bytes(code, 'utf-8') if not code is None else None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment