Monday, January 7, 2013

Purereadline

I have been playing with SL4A (the Android scripting layer) and PY4A (Python for Android) and I wanted to see if I could get the readline package working. Readline is based on GNU's libreadline. So I was able to compile libreadline.so, but I was too lazy to build Python properly for bionic (androids version of libc) in order to get a working Python header file. This got me thinking that a standalone pure Python version of readline could be useful for anyone without the Python headers (python.h and pyconfig.h).

Download a tarball of libreadline.so and libhistory.so for bionic from my public dropbox.

FYI: I copied these shared object libraries into /data/data/com.googlecode.pythonforandroid/files/python/lib, made symlinks to remove the version number, changed the permissions to 755 and the ownership to PY4A's username and group, which I represent below as app_XX. Alternately, if you don't have root permission, you still have permissions to use sl4a's folder when using either py4a or their bash shell, so put your shared objects there instead.

    /data/data/com.googlecode.androidscripting/files/python/lib

~$ wget https://dl.dropbox.com/u/19049582/rl-6.2_arm_linux_androideabi.tar
~$ tar -xf rl-6.2_arm_linux_androideabi.tar
~$ cp rl-6.2_arm_linux_androideabi.tar/libreadline.so.6.2 /data/data/com.googlecode.pythonforandroid/files/python/lib
~$ cp rl-6.2_arm_linux_androideabi.tar/libhistory.so.6.2 /data/data/com.googlecode.pythonforandroid/files/python/lib
~$ cd /data/data/com.googlecode.pythonforandroid/files/python/lib
/data/data/com.googlecode.pythonforandroid/files/python/lib$ ln libreadline.so.6.2 libreadline.so
/data/data/com.googlecode.pythonforandroid/files/python/lib$ ln libhistory.so.6.2 libhistory.so
/data/data/com.googlecode.pythonforandroid/files/python/lib$ chmod 755 libreadline.so
/data/data/com.googlecode.pythonforandroid/files/python/lib$ chmod 755 libhistory.so
/data/data/com.googlecode.pythonforandroid/files/python/lib$ chown app_XX:app_XX libreadline.so
/data/data/com.googlecode.pythonforandroid/files/python/lib$ chown app_XX:app_XX libhistory.so

You can test them in the SL4A interpreter by running the following script:

>>> from ctypes import *
>>> rl = CDLL("libreadline.so")
>>> rl.rl_initialize()
>>>  rl_completer_word_break_characters = c_char_p.in_dll(rl, " rl_completer_word_break_characters")
>>> print rl_completer_word_break_characters
" \t\n\"\\'`@$><=;|&{("

Therefore I present purereadline, an all Python wrapper for libreadline using ctypes. Uh ... it's still in beta, and I don't even know if it will work, but I can't think of any reason why it wouldn't. I can use ctypes fine with the shared object libraries to run functions and get exported variables. The shared object libraries compile very nicely using c4droid although I had to patch setpwent.

See issue #6 on py4a for more information and links.
Fork me on GitHub