From 93f7384cc4b79dbf23115e04a62d64783c07bee7 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 15:54:31 -0700 Subject: [PATCH 01/21] Work on lxml --- pythonforandroid/recipes/libxml2/__init__.py | 35 +++++++++++++++ pythonforandroid/recipes/libxslt/__init__.py | 33 ++++++++++++++ .../recipes/libxslt/fix-dlopen.patch | 11 +++++ pythonforandroid/recipes/lxml/__init__.py | 45 +++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 pythonforandroid/recipes/libxml2/__init__.py create mode 100644 pythonforandroid/recipes/libxslt/__init__.py create mode 100644 pythonforandroid/recipes/libxslt/fix-dlopen.patch create mode 100644 pythonforandroid/recipes/lxml/__init__.py diff --git a/pythonforandroid/recipes/libxml2/__init__.py b/pythonforandroid/recipes/libxml2/__init__.py new file mode 100644 index 0000000000..e623fd7a64 --- /dev/null +++ b/pythonforandroid/recipes/libxml2/__init__.py @@ -0,0 +1,35 @@ +from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory +from os.path import exists, join +import sh + +class Libxml2Recipe(Recipe): + version = '2.7.8' + url = 'http://xmlsoft.org/sources/libxml2-{version}.tar.gz' + depends = [] + + def should_build(self, arch): + super(Libxml2Recipe, self).should_build(arch) + return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) + + def build_arch(self, arch): + super(Libxml2Recipe, self).build_arch(arch) + env = self.get_recipe_env(arch) + with current_directory(self.get_build_dir(arch.arch)): + # If the build is done with /bin/sh things blow up, + # try really hard to use bash + bash = sh.Command('/bin/bash') + sed = sh.Command('sed') + make = sh.Command('make') + shprint(bash, 'configure', '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', + '--without-modules', '--without-legacy', '--without-history', '--without-debug', '--without-docbook', '--without-python', '--without-threads') + shprint(make, _env=env) + shutil.copyfile('.libs/libxml2.a', join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) + + + def get_recipe_env(self, arch): + env = super(Libxml2Recipe, self).get_recipe_env(arch) + env['CONFIG_SHELL'] = '/bin/bash' + env['SHELL'] = '/bin/bash' + return env + +recipe = Libxml2Recipe() diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py new file mode 100644 index 0000000000..a1abf20ff9 --- /dev/null +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -0,0 +1,33 @@ +from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory +from os.path import exists, join +import sh + +class LibxsltRecipe(Recipe): + version = '1.1.28' + url = 'http://xmlsoft.org/sources/libxslt-{version}.tar.gz' + depends = ['libxml2'] + patches = ['fix-dlopen.patch'] + + def should_build(self, arch): + super(LibxsltRecipe, self).should_build(arch) + return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) + + def build_arch(self, arch): + super(LibxsltRecipe, self).build_arch(arch) + env = self.get_recipe_env(arch) + with current_directory(self.get_build_dir(arch.arch)): + bash = sh.Command('bash') + shprint(bash, 'configure', + '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', + '--without-plugins', '--without-debug', '--without-python', '--without-crypto', + '--with-libxml-src=$BUILD_libxml2') + shprint(sh.make, _env=env) + shutil.copyfile('src/libxslt/.libs/libxslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) + + + def get_recipe_env(self, arch): + env = super(LibXml2Recipe, self).get_recipe_env(arch) + env['CFLAGS'] += ' -Os' + return env + +recipe = LibxsltRecipe() diff --git a/pythonforandroid/recipes/libxslt/fix-dlopen.patch b/pythonforandroid/recipes/libxslt/fix-dlopen.patch new file mode 100644 index 0000000000..34d56b6e01 --- /dev/null +++ b/pythonforandroid/recipes/libxslt/fix-dlopen.patch @@ -0,0 +1,11 @@ +--- libxslt-1.1.27.orig/python/libxsl.py 2012-09-04 16:26:23.000000000 +0200 ++++ libxslt-1.1.27/python/libxsl.py 2013-07-29 15:11:04.182227378 +0200 +@@ -4,7 +4,7 @@ + # loader to work in that mode if feasible + # + import sys +-if not hasattr(sys,'getdlopenflags'): ++if True: + import libxml2mod + import libxsltmod + import libxml2 diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py new file mode 100644 index 0000000000..0689368bad --- /dev/null +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -0,0 +1,45 @@ +from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory +from os.path import exists, join +import sh + +class LXMLRecipe(Recipe): + version = '3.6.0' + url = 'https://pypi.python.org/packages/source/l/lxml/lxml-{version}.tar.gz' + depends = ['python2', 'libxml2', 'libxslt'] + + def should_build(self, arch): + super(LXMLRecipe, self).should_build(arch) + return not exists(join(self.ctx.get_libs_dir(arch.arch), 'liblxml.so')) + + def build_arch(self, arch): + super(LXMLRecipe, self).build_arch(arch) + env = self.get_recipe_env(arch) + with current_directory(self.get_build_dir(arch.arch)): + #chmod +x $BUILD_libxslt/xslt-config + bash = sh.Command('bash') + shprint(bash, 'configure', '--enable-minimal', '--disable-soname-versions', '--host=arm-linux-androideabi', '--enable-shared', _env=env) + shprint(sh.make, _env=env) + shutil.copyfile('src/liblxml/.libs/libsodium.so', join(self.ctx.get_libs_dir(arch.arch), 'libsodium.so')) + + + """ try $HOSTPYTHON setup.py build_ext -I$BUILD_libxml2/include -I$BUILD_libxslt + try find . -iname '*.pyx' -exec $CYTHON {} \; + try $HOSTPYTHON setup.py build_ext -v + try find build/lib.* -name "*.o" -exec $STRIP {} \; + + export PYTHONPATH=$BUILD_hostpython/Lib/site-packages + try $BUILD_hostpython/hostpython setup.py install -O2 --root=$BUILD_PATH/python-install --install-lib=lib/python2.7/site-packages + + unset LDSHARED + pop_arm""" + + def get_recipe_env(self, arch): + env = super(LibsodiumRecipe, self).get_recipe_env(arch) + env['CC'] += "-I$BUILD_libxml2/include -I$BUILD_libxslt" + env['LDFLAGS'] = "-L$BUILD_libxslt/libxslt/.libs -L$BUILD_libxslt/libexslt/.libs -L$BUILD_libxml2/.libs -L$BUILD_libxslt/libxslt -L$BUILD_libxslt/libexslt -L$BUILD_libxml2/ " + env['LDFLAGS'] + env['LDSHARED'] = "$LIBLINK" + env['PATH'] += ":$BUILD_libxslt" + env['CFLAGS'] += ' -Os' + return env + +recipe = LXMLRecipe() From 14e5fd13873b2b88aa8515689ee460fe1984a540 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 16:38:03 -0700 Subject: [PATCH 02/21] Fix libxslt configure libxml path --- pythonforandroid/recipes/libxslt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py index a1abf20ff9..7bd6143d64 100644 --- a/pythonforandroid/recipes/libxslt/__init__.py +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -20,13 +20,13 @@ def build_arch(self, arch): shprint(bash, 'configure', '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', '--without-plugins', '--without-debug', '--without-python', '--without-crypto', - '--with-libxml-src=$BUILD_libxml2') + '--with-libxml-src=../../../libxml2/armeabi/libxml2/') shprint(sh.make, _env=env) shutil.copyfile('src/libxslt/.libs/libxslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) def get_recipe_env(self, arch): - env = super(LibXml2Recipe, self).get_recipe_env(arch) + env = super(LibxsltRecipe, self).get_recipe_env(arch) env['CFLAGS'] += ' -Os' return env From 29aaaa4189af454be3685900a7d89d12eaac8c53 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 16:59:24 -0700 Subject: [PATCH 03/21] Libxslt finally builds --- pythonforandroid/recipes/libxslt/__init__.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py index 7bd6143d64..1cd43fb1cc 100644 --- a/pythonforandroid/recipes/libxslt/__init__.py +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -1,5 +1,5 @@ from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory -from os.path import exists, join +from os.path import exists, join, dirname, basename import sh class LibxsltRecipe(Recipe): @@ -16,18 +16,21 @@ def build_arch(self, arch): super(LibxsltRecipe, self).build_arch(arch) env = self.get_recipe_env(arch) with current_directory(self.get_build_dir(arch.arch)): - bash = sh.Command('bash') - shprint(bash, 'configure', + # If the build is done with /bin/sh things blow up, + # try really hard to use bash + libxml = dirname(dirname(self.get_build_container_dir(arch.arch))) + "/libxml2/%s/libxml2" % arch.arch + shprint(sh.Command('./configure'), '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', '--without-plugins', '--without-debug', '--without-python', '--without-crypto', - '--with-libxml-src=../../../libxml2/armeabi/libxml2/') + '--with-libxml-src=%s' % libxml) shprint(sh.make, _env=env) - shutil.copyfile('src/libxslt/.libs/libxslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) + shutil.copyfile('libxslt/.libs/libxslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) def get_recipe_env(self, arch): env = super(LibxsltRecipe, self).get_recipe_env(arch) - env['CFLAGS'] += ' -Os' + env['CONFIG_SHELL'] = '/bin/bash' + env['SHELL'] = '/bin/bash' return env recipe = LibxsltRecipe() From 45231afff4d1749bdeab747c06eb82a33952ace4 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 17:37:51 -0700 Subject: [PATCH 04/21] WIP Lxml recipe --- pythonforandroid/recipes/lxml/__init__.py | 37 +++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 0689368bad..343376a973 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -9,36 +9,33 @@ class LXMLRecipe(Recipe): def should_build(self, arch): super(LXMLRecipe, self).should_build(arch) + return True return not exists(join(self.ctx.get_libs_dir(arch.arch), 'liblxml.so')) def build_arch(self, arch): - super(LXMLRecipe, self).build_arch(arch) env = self.get_recipe_env(arch) with current_directory(self.get_build_dir(arch.arch)): - #chmod +x $BUILD_libxslt/xslt-config - bash = sh.Command('bash') - shprint(bash, 'configure', '--enable-minimal', '--disable-soname-versions', '--host=arm-linux-androideabi', '--enable-shared', _env=env) - shprint(sh.make, _env=env) - shutil.copyfile('src/liblxml/.libs/libsodium.so', join(self.ctx.get_libs_dir(arch.arch), 'libsodium.so')) - + hostpython = sh.Command(self.ctx.hostpython) + shprint(hostpython, + 'setup.py', + 'build_ext', + "-p%s" % arch.arch, + "-I/home/zgoldberg/.local/share/python-for-android/dists/peggo-python/python-install/include/python2.7/pyconfig.h", + "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/include", + "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" - """ try $HOSTPYTHON setup.py build_ext -I$BUILD_libxml2/include -I$BUILD_libxslt - try find . -iname '*.pyx' -exec $CYTHON {} \; - try $HOSTPYTHON setup.py build_ext -v - try find build/lib.* -name "*.o" -exec $STRIP {} \; + , _env=env) - export PYTHONPATH=$BUILD_hostpython/Lib/site-packages - try $BUILD_hostpython/hostpython setup.py install -O2 --root=$BUILD_PATH/python-install --install-lib=lib/python2.7/site-packages - - unset LDSHARED - pop_arm""" + super(LXMLRecipe, self).build_arch(arch) def get_recipe_env(self, arch): - env = super(LibsodiumRecipe, self).get_recipe_env(arch) - env['CC'] += "-I$BUILD_libxml2/include -I$BUILD_libxslt" - env['LDFLAGS'] = "-L$BUILD_libxslt/libxslt/.libs -L$BUILD_libxslt/libexslt/.libs -L$BUILD_libxml2/.libs -L$BUILD_libxslt/libxslt -L$BUILD_libxslt/libexslt -L$BUILD_libxml2/ " + env['LDFLAGS'] + env = super(LXMLRecipe, self).get_recipe_env(arch) + bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" + bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" + env['CC'] += " -I%s/include -I%s" % (bxml, bxsl) + env['LDFLAGS'] = (" -L%s/libxslt/.libs -L%s/libexslt/.libs -L%s/.libs -L%s/libxslt -L%s/libexslt -L%s/ " % (bxsl, bxsl, bxml, bxsl, bxsl, bxml)) + env['LDFLAGS'] env['LDSHARED'] = "$LIBLINK" - env['PATH'] += ":$BUILD_libxslt" + env['PATH'] += ":%s" % bxsl env['CFLAGS'] += ' -Os' return env From 3b64104ab3537b802045c5b70a06165f35a067fd Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 18:54:27 -0700 Subject: [PATCH 05/21] More attempts to fix things, mostly useless --- pythonforandroid/recipes/libxml2/__init__.py | 8 ++--- pythonforandroid/recipes/lxml/__init__.py | 37 ++++++++++++++++---- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/pythonforandroid/recipes/libxml2/__init__.py b/pythonforandroid/recipes/libxml2/__init__.py index e623fd7a64..3480ccce2e 100644 --- a/pythonforandroid/recipes/libxml2/__init__.py +++ b/pythonforandroid/recipes/libxml2/__init__.py @@ -17,12 +17,10 @@ def build_arch(self, arch): with current_directory(self.get_build_dir(arch.arch)): # If the build is done with /bin/sh things blow up, # try really hard to use bash - bash = sh.Command('/bin/bash') sed = sh.Command('sed') - make = sh.Command('make') - shprint(bash, 'configure', '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', - '--without-modules', '--without-legacy', '--without-history', '--without-debug', '--without-docbook', '--without-python', '--without-threads') - shprint(make, _env=env) + shprint(sh.Command('./configure'), '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', + '--without-modules', '--without-legacy', '--without-history', '--without-debug', '--without-docbook', '--without-python', '--without-threads', '--without-iconv') + shprint(sh.make, _env=env) shutil.copyfile('.libs/libxml2.a', join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 343376a973..dd75e77a5f 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -1,4 +1,6 @@ from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory +from pythonforandroid.util import current_directory, ensure_dir +from pythonforandroid.logger import debug, shprint, info from os.path import exists, join import sh @@ -6,6 +8,7 @@ class LXMLRecipe(Recipe): version = '3.6.0' url = 'https://pypi.python.org/packages/source/l/lxml/lxml-{version}.tar.gz' depends = ['python2', 'libxml2', 'libxslt'] + name = 'lxml' def should_build(self, arch): super(LXMLRecipe, self).should_build(arch) @@ -14,17 +17,29 @@ def should_build(self, arch): def build_arch(self, arch): env = self.get_recipe_env(arch) + env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/png -I{jni_path}/jpeg'.format( + jni_path=join(self.ctx.bootstrap.build_dir, 'jni')) + env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/sdl/include -I{jni_path}/sdl_mixer'.format( + jni_path=join(self.ctx.bootstrap.build_dir, 'jni')) + env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/sdl_ttf -I{jni_path}/sdl_image'.format( + jni_path=join(self.ctx.bootstrap.build_dir, 'jni')) + debug('pygame cflags', env['CFLAGS']) + + + env['LDFLAGS'] = env['LDFLAGS'] + ' -L{libs_path} -L{src_path}/obj/local/{arch} -lm -lz'.format( + libs_path=self.ctx.libs_dir, src_path=self.ctx.bootstrap.build_dir, arch=env['ARCH']) + + env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') + with current_directory(self.get_build_dir(arch.arch)): + info('hostpython is ' + self.ctx.hostpython) hostpython = sh.Command(self.ctx.hostpython) - shprint(hostpython, - 'setup.py', + shprint(hostpython, 'setup.py', 'build_ext', - "-p%s" % arch.arch, "-I/home/zgoldberg/.local/share/python-for-android/dists/peggo-python/python-install/include/python2.7/pyconfig.h", "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/include", - "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" - - , _env=env) + "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt", + _tail=10000, _critical=True, _env=env) super(LXMLRecipe, self).build_arch(arch) @@ -37,6 +52,16 @@ def get_recipe_env(self, arch): env['LDSHARED'] = "$LIBLINK" env['PATH'] += ":%s" % bxsl env['CFLAGS'] += ' -Os' + env['LDFLAGS'] = env['LDFLAGS'] + ' -L{}'.format( + self.ctx.get_libs_dir(arch.arch)) + env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') + env['LIBLINK'] = 'NOTNONE' + env['NDKPLATFORM'] = self.ctx.ndk_platform + + # Every recipe uses its own liblink path, object files are collected and biglinked later + liblink_path = join(self.get_build_container_dir(arch.arch), 'objects_{}'.format(self.name)) + env['LIBLINK_PATH'] = liblink_path + ensure_dir(liblink_path) return env recipe = LXMLRecipe() From a9746a87889c5305d0ebef15f8accf66b9cb1c79 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 20:08:57 -0700 Subject: [PATCH 06/21] Not exactly working yet --- pythonforandroid/recipes/lxml/__init__.py | 26 ++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index dd75e77a5f..57cc310bb6 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -3,6 +3,7 @@ from pythonforandroid.logger import debug, shprint, info from os.path import exists, join import sh +import glob class LXMLRecipe(Recipe): version = '3.6.0' @@ -41,6 +42,28 @@ def build_arch(self, arch): "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt", _tail=10000, _critical=True, _env=env) + build_lib = glob.glob('./build/lib*') + assert len(build_lib) == 1 + + shprint(sh.find, ".", '-iname', '*.pyx', '-exec', + env['CYTHON'], '{}', ';') + + shprint(hostpython, 'setup.py', + 'build_ext', "-v", + _tail=10000, _critical=True, _env=env) + + shprint(sh.find, build_lib[0], '-name', '*.o', '-exec', + env['STRIP'], '{}', ';') + + shprint(hostpython, 'setup.py', + 'install', "-O2", + _tail=10000, _critical=True, _env=env) + + #env['PYTHONPATH'] += $BUILD_hostpython/Lib/site-packages + #try $BUILD_hostpython/hostpython setup.py install -O2 --root=$BUILD_PATH/python-install --install-lib=lib/python2.7/site-packages + + + super(LXMLRecipe, self).build_arch(arch) def get_recipe_env(self, arch): @@ -48,7 +71,8 @@ def get_recipe_env(self, arch): bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" env['CC'] += " -I%s/include -I%s" % (bxml, bxsl) - env['LDFLAGS'] = (" -L%s/libxslt/.libs -L%s/libexslt/.libs -L%s/.libs -L%s/libxslt -L%s/libexslt -L%s/ " % (bxsl, bxsl, bxml, bxsl, bxsl, bxml)) + env['LDFLAGS'] + env['LDFLAGS'] = (" -L%s/libxslt/.libs -L%s/.libs -L%s/libxslt -L%s/ " % (bxsl, bxsl, bxml, bxsl)) + env['LDFLAGS'] + env['CYTHON'] = "cython" env['LDSHARED'] = "$LIBLINK" env['PATH'] += ":%s" % bxsl env['CFLAGS'] += ' -Os' From 08072da47f2b264d76daae5d5f2e51cf516e2a88 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 21:36:58 -0700 Subject: [PATCH 07/21] This should work, but doesn't. Go figure. --- pythonforandroid/recipes/levenshtein/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 pythonforandroid/recipes/levenshtein/__init__.py diff --git a/pythonforandroid/recipes/levenshtein/__init__.py b/pythonforandroid/recipes/levenshtein/__init__.py new file mode 100644 index 0000000000..22a1e2c0ec --- /dev/null +++ b/pythonforandroid/recipes/levenshtein/__init__.py @@ -0,0 +1,14 @@ +from pythonforandroid.toolchain import CompiledComponentsPythonRecipe + + +class LevenshteinRecipe(CompiledComponentsPythonRecipe): + name="levenshtein" + version = '0.12.0' + url = 'https://pypi.python.org/packages/source/p/python-Levenshtein/python-Levenshtein-{version}.tar.gz' + depends = [('python2', 'python3'), 'setuptools'] + + call_hostpython_via_targetpython = False + install_in_targetpython = False + install_in_hostpython = True + +recipe = LevenshteinRecipe() From 06f9191e99eb991458775fa6ae08c3ee4060b31a Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 21:46:15 -0700 Subject: [PATCH 08/21] Try using the correct superclass for lxml --- pythonforandroid/recipes/lxml/__init__.py | 8 ++++++-- pythonforandroid/recipes/sqlalchemy/__init__.py | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 57cc310bb6..7712f26da7 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -1,21 +1,25 @@ from pythonforandroid.toolchain import Recipe, shprint, shutil, current_directory +from pythonforandroid.toolchain import CompiledComponentsPythonRecipe from pythonforandroid.util import current_directory, ensure_dir from pythonforandroid.logger import debug, shprint, info from os.path import exists, join import sh import glob -class LXMLRecipe(Recipe): +class LXMLRecipe(CompiledComponentsPythonRecipe): version = '3.6.0' url = 'https://pypi.python.org/packages/source/l/lxml/lxml-{version}.tar.gz' depends = ['python2', 'libxml2', 'libxslt'] name = 'lxml' + call_hostpython_via_targetpython = False # Due to setuptools + def should_build(self, arch): super(LXMLRecipe, self).should_build(arch) return True return not exists(join(self.ctx.get_libs_dir(arch.arch), 'liblxml.so')) + """ def build_arch(self, arch): env = self.get_recipe_env(arch) env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/png -I{jni_path}/jpeg'.format( @@ -65,7 +69,7 @@ def build_arch(self, arch): super(LXMLRecipe, self).build_arch(arch) - + """ def get_recipe_env(self, arch): env = super(LXMLRecipe, self).get_recipe_env(arch) bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" diff --git a/pythonforandroid/recipes/sqlalchemy/__init__.py b/pythonforandroid/recipes/sqlalchemy/__init__.py index 79e0ebf8fc..2c4771baae 100644 --- a/pythonforandroid/recipes/sqlalchemy/__init__.py +++ b/pythonforandroid/recipes/sqlalchemy/__init__.py @@ -1,4 +1,3 @@ - from pythonforandroid.toolchain import CompiledComponentsPythonRecipe @@ -6,9 +5,9 @@ class SQLAlchemyRecipe(CompiledComponentsPythonRecipe): name = 'sqlalchemy' version = '1.0.9' url = 'https://pypi.python.org/packages/source/S/SQLAlchemy/SQLAlchemy-{version}.tar.gz' - + depends = [('python2', 'python3'), 'setuptools'] - + patches = ['zipsafe.patch'] From 15837208354d20559ed8b6077b2d9a8b33bad03d Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Tue, 19 Apr 2016 21:48:34 -0700 Subject: [PATCH 09/21] Renable levenshtein build --- pythonforandroid/recipes/levenshtein/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pythonforandroid/recipes/levenshtein/__init__.py b/pythonforandroid/recipes/levenshtein/__init__.py index 22a1e2c0ec..ba8d1bcd93 100644 --- a/pythonforandroid/recipes/levenshtein/__init__.py +++ b/pythonforandroid/recipes/levenshtein/__init__.py @@ -8,7 +8,5 @@ class LevenshteinRecipe(CompiledComponentsPythonRecipe): depends = [('python2', 'python3'), 'setuptools'] call_hostpython_via_targetpython = False - install_in_targetpython = False - install_in_hostpython = True recipe = LevenshteinRecipe() From 4b742d6fac07b2f0802d7c0ca79c9fa8fd431a19 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 21:21:40 -0700 Subject: [PATCH 10/21] Still working on this build thing --- pythonforandroid/recipes/libxml2/__init__.py | 20 +++++- pythonforandroid/recipes/libxslt/__init__.py | 2 + pythonforandroid/recipes/lxml/__init__.py | 76 +++----------------- 3 files changed, 30 insertions(+), 68 deletions(-) diff --git a/pythonforandroid/recipes/libxml2/__init__.py b/pythonforandroid/recipes/libxml2/__init__.py index 3480ccce2e..e632a6cfad 100644 --- a/pythonforandroid/recipes/libxml2/__init__.py +++ b/pythonforandroid/recipes/libxml2/__init__.py @@ -6,20 +6,32 @@ class Libxml2Recipe(Recipe): version = '2.7.8' url = 'http://xmlsoft.org/sources/libxml2-{version}.tar.gz' depends = [] + patches = ['add-glob.c.patch'] def should_build(self, arch): super(Libxml2Recipe, self).should_build(arch) + return True return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) def build_arch(self, arch): super(Libxml2Recipe, self).build_arch(arch) env = self.get_recipe_env(arch) with current_directory(self.get_build_dir(arch.arch)): + # First we need to build glob.c because its not avail + # in android ndk + + + shprint(sh.Command(env['CC'].split(" ")[0]), env['CC'].split(" ")[1], "-c", "-I.", "glob.c") + shprint(sh.Command("chmod"), "+x", "glob.o") + + env['LIBS'] = "./glob.o" + # If the build is done with /bin/sh things blow up, # try really hard to use bash sed = sh.Command('sed') - shprint(sh.Command('./configure'), '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', - '--without-modules', '--without-legacy', '--without-history', '--without-debug', '--without-docbook', '--without-python', '--without-threads', '--without-iconv') + shprint(sh.Command('./configure'), '--host=arm-linux-eabi', + '--without-modules', '--without-legacy', '--without-hfinistory', '--without-debug', '--without-docbook', '--without-python', '--without-threads', '--without-iconv', + _env=env) shprint(sh.make, _env=env) shutil.copyfile('.libs/libxml2.a', join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) @@ -28,6 +40,10 @@ def get_recipe_env(self, arch): env = super(Libxml2Recipe, self).get_recipe_env(arch) env['CONFIG_SHELL'] = '/bin/bash' env['SHELL'] = '/bin/bash' + env['CC'] = '/usr/bin/ccache arm-linux-androideabi-gcc -DANDROID -mandroid -fomit-frame-pointer' + env['CCC'] = '/usr/bin/ccache arm-linux-androideabi-g++ -DANDROID -mandroid -fomit-frame-pointer' + #--sysroot /opt/android-sdks/ndk-bundle/platforms/android-16/arch-arm -I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2//include -I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt -I/home/zgoldberg/.local/share/python-for-android/build/python-installs/peggo-python/include/python2.7 + return env recipe = Libxml2Recipe() diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py index 1cd43fb1cc..673df77f4f 100644 --- a/pythonforandroid/recipes/libxslt/__init__.py +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -8,6 +8,8 @@ class LibxsltRecipe(Recipe): depends = ['libxml2'] patches = ['fix-dlopen.patch'] + call_hostpython_via_targetpython = False + def should_build(self, arch): super(LibxsltRecipe, self).should_build(arch) return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 7712f26da7..0e25b2cf3a 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -2,7 +2,7 @@ from pythonforandroid.toolchain import CompiledComponentsPythonRecipe from pythonforandroid.util import current_directory, ensure_dir from pythonforandroid.logger import debug, shprint, info -from os.path import exists, join +from os.path import exists, join, dirname import sh import glob @@ -19,77 +19,21 @@ def should_build(self, arch): return True return not exists(join(self.ctx.get_libs_dir(arch.arch), 'liblxml.so')) - """ - def build_arch(self, arch): - env = self.get_recipe_env(arch) - env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/png -I{jni_path}/jpeg'.format( - jni_path=join(self.ctx.bootstrap.build_dir, 'jni')) - env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/sdl/include -I{jni_path}/sdl_mixer'.format( - jni_path=join(self.ctx.bootstrap.build_dir, 'jni')) - env['CFLAGS'] = env['CFLAGS'] + ' -I{jni_path}/sdl_ttf -I{jni_path}/sdl_image'.format( - jni_path=join(self.ctx.bootstrap.build_dir, 'jni')) - debug('pygame cflags', env['CFLAGS']) - - - env['LDFLAGS'] = env['LDFLAGS'] + ' -L{libs_path} -L{src_path}/obj/local/{arch} -lm -lz'.format( - libs_path=self.ctx.libs_dir, src_path=self.ctx.bootstrap.build_dir, arch=env['ARCH']) - - env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') - - with current_directory(self.get_build_dir(arch.arch)): - info('hostpython is ' + self.ctx.hostpython) - hostpython = sh.Command(self.ctx.hostpython) - shprint(hostpython, 'setup.py', - 'build_ext', - "-I/home/zgoldberg/.local/share/python-for-android/dists/peggo-python/python-install/include/python2.7/pyconfig.h", - "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/include", - "-I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt", - _tail=10000, _critical=True, _env=env) - - build_lib = glob.glob('./build/lib*') - assert len(build_lib) == 1 - - shprint(sh.find, ".", '-iname', '*.pyx', '-exec', - env['CYTHON'], '{}', ';') - - shprint(hostpython, 'setup.py', - 'build_ext', "-v", - _tail=10000, _critical=True, _env=env) - - shprint(sh.find, build_lib[0], '-name', '*.o', '-exec', - env['STRIP'], '{}', ';') - - shprint(hostpython, 'setup.py', - 'install', "-O2", - _tail=10000, _critical=True, _env=env) - - #env['PYTHONPATH'] += $BUILD_hostpython/Lib/site-packages - #try $BUILD_hostpython/hostpython setup.py install -O2 --root=$BUILD_PATH/python-install --install-lib=lib/python2.7/site-packages - - - - super(LXMLRecipe, self).build_arch(arch) - """ def get_recipe_env(self, arch): env = super(LXMLRecipe, self).get_recipe_env(arch) bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" - env['CC'] += " -I%s/include -I%s" % (bxml, bxsl) - env['LDFLAGS'] = (" -L%s/libxslt/.libs -L%s/.libs -L%s/libxslt -L%s/ " % (bxsl, bxsl, bxml, bxsl)) + env['LDFLAGS'] - env['CYTHON'] = "cython" - env['LDSHARED'] = "$LIBLINK" - env['PATH'] += ":%s" % bxsl - env['CFLAGS'] += ' -Os' - env['LDFLAGS'] = env['LDFLAGS'] + ' -L{}'.format( - self.ctx.get_libs_dir(arch.arch)) + targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) + env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) + #env['LDSHARED'] = ENV['CC'] env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') - env['LIBLINK'] = 'NOTNONE' - env['NDKPLATFORM'] = self.ctx.ndk_platform + # WTH is liblink? + env['LDSHARED'] = env['LIBLINK'] + # This linking almost works. Going to have to muck with LDSHARED to + # include the libs_collection folder + #zgoldberg@badass:~/.local/share/python-for-android/build/other_builds/lxml/armeabi/lxml (master)$ /usr/bin/ccache arm-linux-androideabi-ld -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2//include -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/.local/share/python-for-android/build/libs_collections/peggo-python/armeabi build/temp.linux-x86_64-2.7/src/lxml/lxml.objectify.o -lxslt -lxml2 -lpython2.7 -lz -lm -o build/lib.linux-x86_64-2.7/lxml/objectify.soi - # Every recipe uses its own liblink path, object files are collected and biglinked later - liblink_path = join(self.get_build_container_dir(arch.arch), 'objects_{}'.format(self.name)) - env['LIBLINK_PATH'] = liblink_path - ensure_dir(liblink_path) + import pdb; pdb.set_trace() return env recipe = LXMLRecipe() From c97da18834aa41637e3e550bccb70bd2dd0ca3b9 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 21:21:52 -0700 Subject: [PATCH 11/21] Add glob --- pythonforandroid/recipes/libxml2/glob.c | 906 ++++++++++++++++++++++++ pythonforandroid/recipes/libxml2/glob.h | 105 +++ 2 files changed, 1011 insertions(+) create mode 100644 pythonforandroid/recipes/libxml2/glob.c create mode 100644 pythonforandroid/recipes/libxml2/glob.h diff --git a/pythonforandroid/recipes/libxml2/glob.c b/pythonforandroid/recipes/libxml2/glob.c new file mode 100644 index 0000000000..cec80ed7ca --- /dev/null +++ b/pythonforandroid/recipes/libxml2/glob.c @@ -0,0 +1,906 @@ +/* + * Natanael Arndt, 2011: removed collate.h dependencies + * (my changes are trivial) + * + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD$"); + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + +/* + * Some notes on multibyte character support: + * 1. Patterns with illegal byte sequences match nothing - even if + * GLOB_NOCHECK is specified. + * 2. Illegal byte sequences in filenames are handled by treating them as + * single-byte characters with a value of the first byte of the sequence + * cast to wchar_t. + * 3. State-dependent encodings are not currently supported. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000000000ULL +#define M_PROTECT 0x4000000000ULL +#define M_MASK 0xffffffffffULL +#define M_CHAR 0x00ffffffffULL + +typedef uint_fast64_t Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_CHAR 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_CHAR)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define ismeta(c) (((c)&M_QUOTE) != 0) + + +static int compare(const void *, const void *); +static int g_Ctoc(const Char *, char *, size_t); +static int g_lstat(Char *, struct stat *, glob_t *); +static DIR *g_opendir(Char *, glob_t *); +static const Char *g_strchr(const Char *, wchar_t); +#ifdef notdef +static Char *g_strcat(Char *, const Char *); +#endif +static int g_stat(Char *, struct stat *, glob_t *); +static int glob0(const Char *, glob_t *, size_t *); +static int glob1(Char *, glob_t *, size_t *); +static int glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *); +static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); +static int globextend(const Char *, glob_t *, size_t *); +static const Char * + globtilde(const Char *, Char *, size_t, glob_t *); +static int globexp1(const Char *, glob_t *, size_t *); +static int globexp2(const Char *, const Char *, glob_t *, int *, size_t *); +static int match(Char *, Char *, Char *); +#ifdef DEBUG +static void qprintf(const char *, Char *); +#endif + +int +glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) +{ + const char *patnext; + size_t limit; + Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; + mbstate_t mbs; + wchar_t wc; + size_t clen; + + patnext = pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + if (flags & GLOB_LIMIT) { + limit = pglob->gl_matchc; + if (limit == 0) + limit = ARG_MAX; + } else + limit = 0; + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN - 1; + if (flags & GLOB_NOESCAPE) { + memset(&mbs, 0, sizeof(mbs)); + while (bufend - bufnext >= MB_CUR_MAX) { + clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); + if (clen == (size_t)-1 || clen == (size_t)-2) + return (GLOB_NOMATCH); + else if (clen == 0) + break; + *bufnext++ = wc; + patnext += clen; + } + } else { + /* Protect the quoted characters. */ + memset(&mbs, 0, sizeof(mbs)); + while (bufend - bufnext >= MB_CUR_MAX) { + if (*patnext == QUOTE) { + if (*++patnext == EOS) { + *bufnext++ = QUOTE | M_PROTECT; + continue; + } + prot = M_PROTECT; + } else + prot = 0; + clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); + if (clen == (size_t)-1 || clen == (size_t)-2) + return (GLOB_NOMATCH); + else if (clen == 0) + break; + *bufnext++ = wc | prot; + patnext += clen; + } + } + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob, &limit); + else + return glob0(patbuf, pglob, &limit); +} + +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +static int +globexp1(const Char *pattern, glob_t *pglob, size_t *limit) +{ + const Char* ptr = pattern; + int rv; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob, limit); + + while ((ptr = g_strchr(ptr, LBRACE)) != NULL) + if (!globexp2(ptr, pattern, pglob, &rv, limit)) + return rv; + + return glob0(pattern, pglob, limit); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int +globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, size_t *limit) +{ + int i; + Char *lm, *ls; + const Char *pe, *pm, *pm1, *pl; + Char patbuf[MAXPATHLEN]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + continue; + *lm = EOS; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + continue; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } + else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) { + *rv = glob0(patbuf, pglob, limit); + return 0; + } + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++) + continue; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pm1; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + continue; + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS;) + continue; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + *rv = globexp1(patbuf, pglob, limit); + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + *rv = 0; + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b, *eb; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* + * Copy up to the end of the string or / + */ + eb = &patbuf[patbuf_len - 1]; + for (p = pattern + 1, h = (char *) patbuf; + h < (char *)eb && *p && *p != SLASH; *h++ = *p++) + continue; + + *h = EOS; + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME first (iff + * we're not running setuid or setgid) and then trying + * the password file + */ + if (issetugid() != 0 || + (h = getenv("HOME")) == NULL) { + if (((h = getlogin()) != NULL && + (pwd = getpwnam(h)) != NULL) || + (pwd = getpwuid(getuid())) != NULL) + h = pwd->pw_dir; + else + return pattern; + } + } + else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; b < eb && *h; *b++ = *h++) + continue; + + /* Append the rest of the pattern */ + while (b < eb && (*b++ = *p++) != EOS) + continue; + *b = EOS; + + return patbuf; +} + + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. + */ +static int +glob0(const Char *pattern, glob_t *pglob, size_t *limit) +{ + const Char *qpatnext; + int err; + size_t oldpathc; + Char *bufnext, c, patbuf[MAXPATHLEN]; + + qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr(qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, pglob, limit)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc) { + if (((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR)))) + return(globextend(pattern, pglob, limit)); + else + return(GLOB_NOMATCH); + } + if (!(pglob->gl_flags & GLOB_NOSORT)) + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + return(0); +} + +static int +compare(const void *p, const void *q) +{ + return(strcmp(*(char **)p, *(char **)q)); +} + +static int +glob1(Char *pattern, glob_t *pglob, size_t *limit) +{ + Char pathbuf[MAXPATHLEN]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, + pattern, pglob, limit)); +} + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +static int +glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, + glob_t *pglob, size_t *limit) +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob)) + return(0); + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) + || (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob) == 0) && + S_ISDIR(sb.st_mode)))) { + if (pathend + 1 > pathend_last) + return (GLOB_ABORTED); + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob, limit)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + if (q + 1 > pathend_last) + return (GLOB_ABORTED); + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) { + if (pathend + 1 > pathend_last) + return (GLOB_ABORTED); + *pathend++ = *pattern++; + } + } else /* Need expansion, recurse. */ + return(glob3(pathbuf, pathend, pathend_last, pattern, p, + pglob, limit)); + } + /* NOTREACHED */ +} + +static int +glob3(Char *pathbuf, Char *pathend, Char *pathend_last, + Char *pattern, Char *restpattern, + glob_t *pglob, size_t *limit) +{ + struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(); + + if (pathend > pathend_last) + return (GLOB_ABORTED); + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + if (g_Ctoc(pathbuf, buf, sizeof(buf))) + return (GLOB_ABORTED); + if (pglob->gl_errfunc(buf, errno) || + pglob->gl_flags & GLOB_ERR) + return (GLOB_ABORTED); + } + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = readdir; + while ((dp = (*readdirfunc)(dirp))) { + char *sc; + Char *dc; + wchar_t wc; + size_t clen; + mbstate_t mbs; + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + memset(&mbs, 0, sizeof(mbs)); + dc = pathend; + sc = dp->d_name; + while (dc < pathend_last) { + clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); + if (clen == (size_t)-1 || clen == (size_t)-2) { + wc = *sc; + clen = 1; + memset(&mbs, 0, sizeof(mbs)); + } + if ((*dc++ = wc) == EOS) + break; + sc += clen; + } + if (!match(pathend, pattern, restpattern)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, --dc, pathend_last, restpattern, + pglob, limit); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accomodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +static int +globextend(const Char *path, glob_t *pglob, size_t *limit) +{ + char **pathv; + size_t i, newsize, len; + char *copy; + const Char *p; + + if (*limit && pglob->gl_pathc > *limit) { + errno = 0; + return (GLOB_NOSPACE); + } + + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); + pathv = pglob->gl_pathv ? + realloc((char *)pglob->gl_pathv, newsize) : + malloc(newsize); + if (pathv == NULL) { + if (pglob->gl_pathv) { + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } + return(GLOB_NOSPACE); + } + + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs + 1; --i > 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + for (p = path; *p++;) + continue; + len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ + if ((copy = malloc(len)) != NULL) { + if (g_Ctoc(path, copy, len)) { + free(copy); + return (GLOB_NOSPACE); + } + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + return(copy == NULL ? GLOB_NOSPACE : 0); +} + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(Char *name, Char *pat, Char *patend) +{ + int ok, negate_range; + Char c, k; + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + if (pat == patend) + return(1); + do + if (match(name, pat, patend)) + return(1); + while (*name++ != EOS); + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) + if ((*pat & M_MASK) == M_RNG) { + if (CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1])) ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(glob_t *pglob) +{ + size_t i; + char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } +} + +static DIR * +g_opendir(Char *str, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (!*str) + strcpy(buf, "."); + else { + if (g_Ctoc(str, buf, sizeof(buf))) + return (NULL); + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} + +static int +g_lstat(Char *fn, struct stat *sb, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) { + errno = ENAMETOOLONG; + return (-1); + } + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(Char *fn, struct stat *sb, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) { + errno = ENAMETOOLONG; + return (-1); + } + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +static const Char * +g_strchr(const Char *str, wchar_t ch) +{ + + do { + if (*str == ch) + return (str); + } while (*str++); + return (NULL); +} + +static int +g_Ctoc(const Char *str, char *buf, size_t len) +{ + mbstate_t mbs; + size_t clen; + + memset(&mbs, 0, sizeof(mbs)); + while (len >= MB_CUR_MAX) { + clen = wcrtomb(buf, *str, &mbs); + if (clen == (size_t)-1) + return (1); + if (*str == L'\0') + return (0); + str++; + buf += clen; + len -= clen; + } + return (1); +} + +#ifdef DEBUG +static void +qprintf(const char *str, Char *s) +{ + Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif diff --git a/pythonforandroid/recipes/libxml2/glob.h b/pythonforandroid/recipes/libxml2/glob.h new file mode 100644 index 0000000000..351b6c46bb --- /dev/null +++ b/pythonforandroid/recipes/libxml2/glob.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)glob.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD$ + */ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +struct stat; +typedef struct { + size_t gl_pathc; /* Count of total paths so far. */ + size_t gl_matchc; /* Count of paths matching pattern. */ + size_t gl_offs; /* Reserved at beginning of gl_pathv. */ + int gl_flags; /* Copy of flags parameter to glob. */ + char **gl_pathv; /* List of paths matching pattern. */ + /* Copy of errfunc parameter to glob. */ + int (*gl_errfunc)(const char *, int); + + /* + * Alternate filesystem access methods for glob; replacement + * versions of closedir(3), readdir(3), opendir(3), stat(2) + * and lstat(2). + */ + void (*gl_closedir)(void *); + struct dirent *(*gl_readdir)(void *); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, struct stat *); + int (*gl_stat)(const char *, struct stat *); +} glob_t; + +#if __POSIX_VISIBLE >= 199209 +/* Believed to have been introduced in 1003.2-1992 */ +#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ +#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ +#define GLOB_ERR 0x0004 /* Return on error. */ +#define GLOB_MARK 0x0008 /* Append / to matching directories. */ +#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ +#define GLOB_NOSORT 0x0020 /* Don't sort. */ +#define GLOB_NOESCAPE 0x2000 /* Disable backslash escaping. */ + +/* Error values returned by glob(3) */ +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK was not set. */ +#define GLOB_NOSYS (-4) /* Obsolete: source comptability only. */ +#endif /* __POSIX_VISIBLE >= 199209 */ + +#if __BSD_VISIBLE +#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ +#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ +#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ +#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ +#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ +#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ +#define GLOB_LIMIT 0x1000 /* limit number of returned paths */ + +/* source compatibility, these are the old names */ +#define GLOB_MAXPATH GLOB_LIMIT +#define GLOB_ABEND GLOB_ABORTED +#endif /* __BSD_VISIBLE */ + +__BEGIN_DECLS +int glob(const char *, int, int (*)(const char *, int), glob_t *); +void globfree(glob_t *); +__END_DECLS + +#endif /* !_GLOB_H_ */ From 58636ba325c45c3ba52838dd6b772d2c0a158520 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 22:14:00 -0700 Subject: [PATCH 12/21] Libxml2 now builds successfully FOR ARM --- pythonforandroid/recipes/libxml2/__init__.py | 21 +++++--------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/pythonforandroid/recipes/libxml2/__init__.py b/pythonforandroid/recipes/libxml2/__init__.py index e632a6cfad..ba4bf7354b 100644 --- a/pythonforandroid/recipes/libxml2/__init__.py +++ b/pythonforandroid/recipes/libxml2/__init__.py @@ -17,22 +17,14 @@ def build_arch(self, arch): super(Libxml2Recipe, self).build_arch(arch) env = self.get_recipe_env(arch) with current_directory(self.get_build_dir(arch.arch)): - # First we need to build glob.c because its not avail - # in android ndk - - - shprint(sh.Command(env['CC'].split(" ")[0]), env['CC'].split(" ")[1], "-c", "-I.", "glob.c") - shprint(sh.Command("chmod"), "+x", "glob.o") - - env['LIBS'] = "./glob.o" - - # If the build is done with /bin/sh things blow up, - # try really hard to use bash - sed = sh.Command('sed') + env['CC'] += " -I%s" % self.get_build_dir(arch.arch) shprint(sh.Command('./configure'), '--host=arm-linux-eabi', '--without-modules', '--without-legacy', '--without-hfinistory', '--without-debug', '--without-docbook', '--without-python', '--without-threads', '--without-iconv', _env=env) - shprint(sh.make, _env=env) + + # Ensure we only build libxml2.la as if we do everything + # we'll need the glob dependency which is a big headache + shprint(sh.make, "libxml2.la", _env=env) shutil.copyfile('.libs/libxml2.a', join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) @@ -41,9 +33,6 @@ def get_recipe_env(self, arch): env['CONFIG_SHELL'] = '/bin/bash' env['SHELL'] = '/bin/bash' env['CC'] = '/usr/bin/ccache arm-linux-androideabi-gcc -DANDROID -mandroid -fomit-frame-pointer' - env['CCC'] = '/usr/bin/ccache arm-linux-androideabi-g++ -DANDROID -mandroid -fomit-frame-pointer' - #--sysroot /opt/android-sdks/ndk-bundle/platforms/android-16/arch-arm -I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2//include -I/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt -I/home/zgoldberg/.local/share/python-for-android/build/python-installs/peggo-python/include/python2.7 - return env recipe = Libxml2Recipe() From 036c09a9e2564edf5366f427a0eff9abd1ef0580 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 22:15:03 -0700 Subject: [PATCH 13/21] Don't always build libxml2 --- pythonforandroid/recipes/libxml2/__init__.py | 1 - pythonforandroid/recipes/lxml/__init__.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pythonforandroid/recipes/libxml2/__init__.py b/pythonforandroid/recipes/libxml2/__init__.py index ba4bf7354b..e49c2e3d3b 100644 --- a/pythonforandroid/recipes/libxml2/__init__.py +++ b/pythonforandroid/recipes/libxml2/__init__.py @@ -10,7 +10,6 @@ class Libxml2Recipe(Recipe): def should_build(self, arch): super(Libxml2Recipe, self).should_build(arch) - return True return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libxml2.a')) def build_arch(self, arch): diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 0e25b2cf3a..30145e1c3b 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -28,7 +28,7 @@ def get_recipe_env(self, arch): #env['LDSHARED'] = ENV['CC'] env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') # WTH is liblink? - env['LDSHARED'] = env['LIBLINK'] + #env['LDSHARED'] = env['LIBLINK'] # This linking almost works. Going to have to muck with LDSHARED to # include the libs_collection folder #zgoldberg@badass:~/.local/share/python-for-android/build/other_builds/lxml/armeabi/lxml (master)$ /usr/bin/ccache arm-linux-androideabi-ld -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2//include -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/.local/share/python-for-android/build/libs_collections/peggo-python/armeabi build/temp.linux-x86_64-2.7/src/lxml/lxml.objectify.o -lxslt -lxml2 -lpython2.7 -lz -lm -o build/lib.linux-x86_64-2.7/lxml/objectify.soi From 0f243c9010e524c586f0bae1ceab7c954434e701 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 22:37:03 -0700 Subject: [PATCH 14/21] Now libxslt is built for arm, for real this time --- pythonforandroid/recipes/libxslt/__init__.py | 8 ++++++-- pythonforandroid/recipes/lxml/__init__.py | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py index 673df77f4f..b6cce520e5 100644 --- a/pythonforandroid/recipes/libxslt/__init__.py +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -20,12 +20,14 @@ def build_arch(self, arch): with current_directory(self.get_build_dir(arch.arch)): # If the build is done with /bin/sh things blow up, # try really hard to use bash + env['CC'] += " -I%s" % self.get_build_dir(arch.arch) libxml = dirname(dirname(self.get_build_container_dir(arch.arch))) + "/libxml2/%s/libxml2" % arch.arch shprint(sh.Command('./configure'), '--build=i686-pc-linux-gnu', '--host=arm-linux-eabi', '--without-plugins', '--without-debug', '--without-python', '--without-crypto', - '--with-libxml-src=%s' % libxml) - shprint(sh.make, _env=env) + '--with-libxml-src=%s' % libxml, + _env=env) + shprint(sh.make, "V=1", _env=env) shutil.copyfile('libxslt/.libs/libxslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) @@ -33,6 +35,8 @@ def get_recipe_env(self, arch): env = super(LibxsltRecipe, self).get_recipe_env(arch) env['CONFIG_SHELL'] = '/bin/bash' env['SHELL'] = '/bin/bash' + env['CC'] = '/usr/bin/ccache arm-linux-androideabi-gcc -DANDROID -mandroid -fomit-frame-pointer' + env['LDSHARED'] = env['CC'] return env recipe = LibxsltRecipe() diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 30145e1c3b..2b714b16eb 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -25,15 +25,14 @@ def get_recipe_env(self, arch): bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) - #env['LDSHARED'] = ENV['CC'] - env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') + env['LDSHARED'] = env['CC'] + #env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') # WTH is liblink? #env['LDSHARED'] = env['LIBLINK'] # This linking almost works. Going to have to muck with LDSHARED to # include the libs_collection folder #zgoldberg@badass:~/.local/share/python-for-android/build/other_builds/lxml/armeabi/lxml (master)$ /usr/bin/ccache arm-linux-androideabi-ld -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2//include -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/.local/share/python-for-android/build/libs_collections/peggo-python/armeabi build/temp.linux-x86_64-2.7/src/lxml/lxml.objectify.o -lxslt -lxml2 -lpython2.7 -lz -lm -o build/lib.linux-x86_64-2.7/lxml/objectify.soi - import pdb; pdb.set_trace() return env recipe = LXMLRecipe() From e226a8c5a5177de6f7c835f124d82f84b98baea9 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 22:41:40 -0700 Subject: [PATCH 15/21] Dont forget exslt --- pythonforandroid/recipes/libxslt/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py index b6cce520e5..10ff9d00a6 100644 --- a/pythonforandroid/recipes/libxslt/__init__.py +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -29,6 +29,7 @@ def build_arch(self, arch): _env=env) shprint(sh.make, "V=1", _env=env) shutil.copyfile('libxslt/.libs/libxslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libxslt.a')) + shutil.copyfile('libexslt/.libs/libexslt.a', join(self.ctx.get_libs_dir(arch.arch), 'libexslt.a')) def get_recipe_env(self, arch): From bc55f7cf7db1ae0516d67f9690c8c9cb3519f9b4 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 22:54:42 -0700 Subject: [PATCH 16/21] OK, I think lxml is now building... --- pythonforandroid/recipes/lxml/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 2b714b16eb..38881d6c95 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -25,7 +25,7 @@ def get_recipe_env(self, arch): bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) - env['LDSHARED'] = env['CC'] + env['LDSHARED'] = '%s -lpython2.7 -nostartfiles' % env['CC'] #env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') # WTH is liblink? #env['LDSHARED'] = env['LIBLINK'] From 949b530616c98c677b22934eb4a46f8b3a106fd2 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Wed, 20 Apr 2016 23:27:11 -0700 Subject: [PATCH 17/21] Copy the .so at the right time --- pythonforandroid/recipes/lxml/__init__.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 38881d6c95..ff53d44364 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -17,7 +17,12 @@ class LXMLRecipe(CompiledComponentsPythonRecipe): def should_build(self, arch): super(LXMLRecipe, self).should_build(arch) return True - return not exists(join(self.ctx.get_libs_dir(arch.arch), 'liblxml.so')) + return not exists(join(self.ctx.get_libs_dir(arch.arch), 'etree.so')) + + def build_arch(self, arch): + super(LXMLRecipe, self).build_arch(arch) + shutil.copyfile('%s/build/lib.linux-x86_64-2.7/lxml/etree.so' % self.get_build_dir(arch.arch), join(self.ctx.get_libs_dir(arch.arch), 'etree.so')) + shutil.copyfile('%s/build/lib.linux-x86_64-2.7/lxml/objectify.so' % self.get_build_dir(arch.arch), join(self.ctx.get_libs_dir(arch.arch), 'objectify.so')) def get_recipe_env(self, arch): env = super(LXMLRecipe, self).get_recipe_env(arch) @@ -26,12 +31,6 @@ def get_recipe_env(self, arch): targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) env['LDSHARED'] = '%s -lpython2.7 -nostartfiles' % env['CC'] - #env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') - # WTH is liblink? - #env['LDSHARED'] = env['LIBLINK'] - # This linking almost works. Going to have to muck with LDSHARED to - # include the libs_collection folder - #zgoldberg@badass:~/.local/share/python-for-android/build/other_builds/lxml/armeabi/lxml (master)$ /usr/bin/ccache arm-linux-androideabi-ld -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2//include -L/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/android-sdks/ndk-bundle/platforms/android-16/arch-arm/usr/lib/ -L/home/zgoldberg/.local/share/python-for-android/build/libs_collections/peggo-python/armeabi build/temp.linux-x86_64-2.7/src/lxml/lxml.objectify.o -lxslt -lxml2 -lpython2.7 -lz -lm -o build/lib.linux-x86_64-2.7/lxml/objectify.soi return env From 1a78df18cfaef1a0be199d7e961293cc5e903fa5 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Thu, 21 Apr 2016 11:22:32 -0700 Subject: [PATCH 18/21] Working lxml?! --- pythonforandroid/recipes/libxslt/__init__.py | 2 +- pythonforandroid/recipes/lxml/__init__.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pythonforandroid/recipes/libxslt/__init__.py b/pythonforandroid/recipes/libxslt/__init__.py index 10ff9d00a6..3b241bf73a 100644 --- a/pythonforandroid/recipes/libxslt/__init__.py +++ b/pythonforandroid/recipes/libxslt/__init__.py @@ -37,7 +37,7 @@ def get_recipe_env(self, arch): env['CONFIG_SHELL'] = '/bin/bash' env['SHELL'] = '/bin/bash' env['CC'] = '/usr/bin/ccache arm-linux-androideabi-gcc -DANDROID -mandroid -fomit-frame-pointer' - env['LDSHARED'] = env['CC'] + env['LDSHARED'] = "%s -nostartfiles -shared -fPIC" % env['CC'] return env recipe = LibxsltRecipe() diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index ff53d44364..438dcfe54e 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -30,8 +30,8 @@ def get_recipe_env(self, arch): bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) - env['LDSHARED'] = '%s -lpython2.7 -nostartfiles' % env['CC'] - + env['LDSHARED'] = '%s -nostartfiles -shared -fPIC -lpython2.7' % env['CC'] + print env['LDSHARED'] return env recipe = LXMLRecipe() From 2b3aea561e92ab493fa854e7cbb27b48cd051e59 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Thu, 21 Apr 2016 11:28:18 -0700 Subject: [PATCH 19/21] Fix levenshtein --- pythonforandroid/recipes/levenshtein/__init__.py | 11 ++++++++++- pythonforandroid/recipes/lxml/__init__.py | 1 - 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pythonforandroid/recipes/levenshtein/__init__.py b/pythonforandroid/recipes/levenshtein/__init__.py index ba8d1bcd93..4b0ed418dc 100644 --- a/pythonforandroid/recipes/levenshtein/__init__.py +++ b/pythonforandroid/recipes/levenshtein/__init__.py @@ -1,5 +1,5 @@ from pythonforandroid.toolchain import CompiledComponentsPythonRecipe - +from os.path import dirname class LevenshteinRecipe(CompiledComponentsPythonRecipe): name="levenshtein" @@ -9,4 +9,13 @@ class LevenshteinRecipe(CompiledComponentsPythonRecipe): call_hostpython_via_targetpython = False + def get_recipe_env(self, arch): + env = super(LevenshteinRecipe, self).get_recipe_env(arch) + bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" + bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" + targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) + env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) + env['LDSHARED'] = '%s -nostartfiles -shared -fPIC -lpython2.7' % env['CC'] + return env + recipe = LevenshteinRecipe() diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 438dcfe54e..337618b4d7 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -31,7 +31,6 @@ def get_recipe_env(self, arch): targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) env['LDSHARED'] = '%s -nostartfiles -shared -fPIC -lpython2.7' % env['CC'] - print env['LDSHARED'] return env recipe = LXMLRecipe() From d50aa291967b6772c31b86c325be53520fd429c7 Mon Sep 17 00:00:00 2001 From: Zachary Goldberg Date: Fri, 24 Jun 2016 10:56:51 -0700 Subject: [PATCH 20/21] Missing add-glob --- .../recipes/libxml2/add-glob.c.patch | 1038 +++++++++++++++++ 1 file changed, 1038 insertions(+) create mode 100644 pythonforandroid/recipes/libxml2/add-glob.c.patch diff --git a/pythonforandroid/recipes/libxml2/add-glob.c.patch b/pythonforandroid/recipes/libxml2/add-glob.c.patch new file mode 100644 index 0000000000..776c0c4d57 --- /dev/null +++ b/pythonforandroid/recipes/libxml2/add-glob.c.patch @@ -0,0 +1,1038 @@ +From c97da18834aa41637e3e550bccb70bd2dd0ca3b9 Mon Sep 17 00:00:00 2001 +From: Zachary Goldberg +Date: Wed, 20 Apr 2016 21:21:52 -0700 +Subject: [PATCH] Add glob + +--- + glob.c | 906 ++++++++++++++++++++++++++++++++ + glob.h | 105 ++++ + 2 files changed, 1011 insertions(+) + create mode 100644 glob.c + create mode 100644 glob.h + +diff --git a/glob.c b/glob.c +new file mode 100644 +index 0000000..cec80ed +--- /dev/null ++++ b/glob.c +@@ -0,0 +1,906 @@ ++/* ++ * Natanael Arndt, 2011: removed collate.h dependencies ++ * (my changes are trivial) ++ * ++ * Copyright (c) 1989, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * This code is derived from software contributed to Berkeley by ++ * Guido van Rossum. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++#if defined(LIBC_SCCS) && !defined(lint) ++static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; ++#endif /* LIBC_SCCS and not lint */ ++#include ++__FBSDID("$FreeBSD$"); ++ ++/* ++ * glob(3) -- a superset of the one defined in POSIX 1003.2. ++ * ++ * The [!...] convention to negate a range is supported (SysV, Posix, ksh). ++ * ++ * Optional extra services, controlled by flags not defined by POSIX: ++ * ++ * GLOB_QUOTE: ++ * Escaping convention: \ inhibits any special meaning the following ++ * character might have (except \ at end of string is retained). ++ * GLOB_MAGCHAR: ++ * Set in gl_flags if pattern contained a globbing character. ++ * GLOB_NOMAGIC: ++ * Same as GLOB_NOCHECK, but it will only append pattern if it did ++ * not contain any magic characters. [Used in csh style globbing] ++ * GLOB_ALTDIRFUNC: ++ * Use alternately specified directory access functions. ++ * GLOB_TILDE: ++ * expand ~user/foo to the /home/dir/of/user/foo ++ * GLOB_BRACE: ++ * expand {1,2}{a,b} to 1a 1b 2a 2b ++ * gl_matchc: ++ * Number of matches in the current invocation of glob. ++ */ ++ ++/* ++ * Some notes on multibyte character support: ++ * 1. Patterns with illegal byte sequences match nothing - even if ++ * GLOB_NOCHECK is specified. ++ * 2. Illegal byte sequences in filenames are handled by treating them as ++ * single-byte characters with a value of the first byte of the sequence ++ * cast to wchar_t. ++ * 3. State-dependent encodings are not currently supported. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DOLLAR '$' ++#define DOT '.' ++#define EOS '\0' ++#define LBRACKET '[' ++#define NOT '!' ++#define QUESTION '?' ++#define QUOTE '\\' ++#define RANGE '-' ++#define RBRACKET ']' ++#define SEP '/' ++#define STAR '*' ++#define TILDE '~' ++#define UNDERSCORE '_' ++#define LBRACE '{' ++#define RBRACE '}' ++#define SLASH '/' ++#define COMMA ',' ++ ++#ifndef DEBUG ++ ++#define M_QUOTE 0x8000000000ULL ++#define M_PROTECT 0x4000000000ULL ++#define M_MASK 0xffffffffffULL ++#define M_CHAR 0x00ffffffffULL ++ ++typedef uint_fast64_t Char; ++ ++#else ++ ++#define M_QUOTE 0x80 ++#define M_PROTECT 0x40 ++#define M_MASK 0xff ++#define M_CHAR 0x7f ++ ++typedef char Char; ++ ++#endif ++ ++ ++#define CHAR(c) ((Char)((c)&M_CHAR)) ++#define META(c) ((Char)((c)|M_QUOTE)) ++#define M_ALL META('*') ++#define M_END META(']') ++#define M_NOT META('!') ++#define M_ONE META('?') ++#define M_RNG META('-') ++#define M_SET META('[') ++#define ismeta(c) (((c)&M_QUOTE) != 0) ++ ++ ++static int compare(const void *, const void *); ++static int g_Ctoc(const Char *, char *, size_t); ++static int g_lstat(Char *, struct stat *, glob_t *); ++static DIR *g_opendir(Char *, glob_t *); ++static const Char *g_strchr(const Char *, wchar_t); ++#ifdef notdef ++static Char *g_strcat(Char *, const Char *); ++#endif ++static int g_stat(Char *, struct stat *, glob_t *); ++static int glob0(const Char *, glob_t *, size_t *); ++static int glob1(Char *, glob_t *, size_t *); ++static int glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *); ++static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); ++static int globextend(const Char *, glob_t *, size_t *); ++static const Char * ++ globtilde(const Char *, Char *, size_t, glob_t *); ++static int globexp1(const Char *, glob_t *, size_t *); ++static int globexp2(const Char *, const Char *, glob_t *, int *, size_t *); ++static int match(Char *, Char *, Char *); ++#ifdef DEBUG ++static void qprintf(const char *, Char *); ++#endif ++ ++int ++glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) ++{ ++ const char *patnext; ++ size_t limit; ++ Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; ++ mbstate_t mbs; ++ wchar_t wc; ++ size_t clen; ++ ++ patnext = pattern; ++ if (!(flags & GLOB_APPEND)) { ++ pglob->gl_pathc = 0; ++ pglob->gl_pathv = NULL; ++ if (!(flags & GLOB_DOOFFS)) ++ pglob->gl_offs = 0; ++ } ++ if (flags & GLOB_LIMIT) { ++ limit = pglob->gl_matchc; ++ if (limit == 0) ++ limit = ARG_MAX; ++ } else ++ limit = 0; ++ pglob->gl_flags = flags & ~GLOB_MAGCHAR; ++ pglob->gl_errfunc = errfunc; ++ pglob->gl_matchc = 0; ++ ++ bufnext = patbuf; ++ bufend = bufnext + MAXPATHLEN - 1; ++ if (flags & GLOB_NOESCAPE) { ++ memset(&mbs, 0, sizeof(mbs)); ++ while (bufend - bufnext >= MB_CUR_MAX) { ++ clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); ++ if (clen == (size_t)-1 || clen == (size_t)-2) ++ return (GLOB_NOMATCH); ++ else if (clen == 0) ++ break; ++ *bufnext++ = wc; ++ patnext += clen; ++ } ++ } else { ++ /* Protect the quoted characters. */ ++ memset(&mbs, 0, sizeof(mbs)); ++ while (bufend - bufnext >= MB_CUR_MAX) { ++ if (*patnext == QUOTE) { ++ if (*++patnext == EOS) { ++ *bufnext++ = QUOTE | M_PROTECT; ++ continue; ++ } ++ prot = M_PROTECT; ++ } else ++ prot = 0; ++ clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); ++ if (clen == (size_t)-1 || clen == (size_t)-2) ++ return (GLOB_NOMATCH); ++ else if (clen == 0) ++ break; ++ *bufnext++ = wc | prot; ++ patnext += clen; ++ } ++ } ++ *bufnext = EOS; ++ ++ if (flags & GLOB_BRACE) ++ return globexp1(patbuf, pglob, &limit); ++ else ++ return glob0(patbuf, pglob, &limit); ++} ++ ++/* ++ * Expand recursively a glob {} pattern. When there is no more expansion ++ * invoke the standard globbing routine to glob the rest of the magic ++ * characters ++ */ ++static int ++globexp1(const Char *pattern, glob_t *pglob, size_t *limit) ++{ ++ const Char* ptr = pattern; ++ int rv; ++ ++ /* Protect a single {}, for find(1), like csh */ ++ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) ++ return glob0(pattern, pglob, limit); ++ ++ while ((ptr = g_strchr(ptr, LBRACE)) != NULL) ++ if (!globexp2(ptr, pattern, pglob, &rv, limit)) ++ return rv; ++ ++ return glob0(pattern, pglob, limit); ++} ++ ++ ++/* ++ * Recursive brace globbing helper. Tries to expand a single brace. ++ * If it succeeds then it invokes globexp1 with the new pattern. ++ * If it fails then it tries to glob the rest of the pattern and returns. ++ */ ++static int ++globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, size_t *limit) ++{ ++ int i; ++ Char *lm, *ls; ++ const Char *pe, *pm, *pm1, *pl; ++ Char patbuf[MAXPATHLEN]; ++ ++ /* copy part up to the brace */ ++ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) ++ continue; ++ *lm = EOS; ++ ls = lm; ++ ++ /* Find the balanced brace */ ++ for (i = 0, pe = ++ptr; *pe; pe++) ++ if (*pe == LBRACKET) { ++ /* Ignore everything between [] */ ++ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) ++ continue; ++ if (*pe == EOS) { ++ /* ++ * We could not find a matching RBRACKET. ++ * Ignore and just look for RBRACE ++ */ ++ pe = pm; ++ } ++ } ++ else if (*pe == LBRACE) ++ i++; ++ else if (*pe == RBRACE) { ++ if (i == 0) ++ break; ++ i--; ++ } ++ ++ /* Non matching braces; just glob the pattern */ ++ if (i != 0 || *pe == EOS) { ++ *rv = glob0(patbuf, pglob, limit); ++ return 0; ++ } ++ ++ for (i = 0, pl = pm = ptr; pm <= pe; pm++) ++ switch (*pm) { ++ case LBRACKET: ++ /* Ignore everything between [] */ ++ for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++) ++ continue; ++ if (*pm == EOS) { ++ /* ++ * We could not find a matching RBRACKET. ++ * Ignore and just look for RBRACE ++ */ ++ pm = pm1; ++ } ++ break; ++ ++ case LBRACE: ++ i++; ++ break; ++ ++ case RBRACE: ++ if (i) { ++ i--; ++ break; ++ } ++ /* FALLTHROUGH */ ++ case COMMA: ++ if (i && *pm == COMMA) ++ break; ++ else { ++ /* Append the current string */ ++ for (lm = ls; (pl < pm); *lm++ = *pl++) ++ continue; ++ /* ++ * Append the rest of the pattern after the ++ * closing brace ++ */ ++ for (pl = pe + 1; (*lm++ = *pl++) != EOS;) ++ continue; ++ ++ /* Expand the current pattern */ ++#ifdef DEBUG ++ qprintf("globexp2:", patbuf); ++#endif ++ *rv = globexp1(patbuf, pglob, limit); ++ ++ /* move after the comma, to the next string */ ++ pl = pm + 1; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ *rv = 0; ++ return 0; ++} ++ ++ ++ ++/* ++ * expand tilde from the passwd file. ++ */ ++static const Char * ++globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) ++{ ++ struct passwd *pwd; ++ char *h; ++ const Char *p; ++ Char *b, *eb; ++ ++ if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) ++ return pattern; ++ ++ /* ++ * Copy up to the end of the string or / ++ */ ++ eb = &patbuf[patbuf_len - 1]; ++ for (p = pattern + 1, h = (char *) patbuf; ++ h < (char *)eb && *p && *p != SLASH; *h++ = *p++) ++ continue; ++ ++ *h = EOS; ++ ++ if (((char *) patbuf)[0] == EOS) { ++ /* ++ * handle a plain ~ or ~/ by expanding $HOME first (iff ++ * we're not running setuid or setgid) and then trying ++ * the password file ++ */ ++ if (issetugid() != 0 || ++ (h = getenv("HOME")) == NULL) { ++ if (((h = getlogin()) != NULL && ++ (pwd = getpwnam(h)) != NULL) || ++ (pwd = getpwuid(getuid())) != NULL) ++ h = pwd->pw_dir; ++ else ++ return pattern; ++ } ++ } ++ else { ++ /* ++ * Expand a ~user ++ */ ++ if ((pwd = getpwnam((char*) patbuf)) == NULL) ++ return pattern; ++ else ++ h = pwd->pw_dir; ++ } ++ ++ /* Copy the home directory */ ++ for (b = patbuf; b < eb && *h; *b++ = *h++) ++ continue; ++ ++ /* Append the rest of the pattern */ ++ while (b < eb && (*b++ = *p++) != EOS) ++ continue; ++ *b = EOS; ++ ++ return patbuf; ++} ++ ++ ++/* ++ * The main glob() routine: compiles the pattern (optionally processing ++ * quotes), calls glob1() to do the real pattern matching, and finally ++ * sorts the list (unless unsorted operation is requested). Returns 0 ++ * if things went well, nonzero if errors occurred. ++ */ ++static int ++glob0(const Char *pattern, glob_t *pglob, size_t *limit) ++{ ++ const Char *qpatnext; ++ int err; ++ size_t oldpathc; ++ Char *bufnext, c, patbuf[MAXPATHLEN]; ++ ++ qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); ++ oldpathc = pglob->gl_pathc; ++ bufnext = patbuf; ++ ++ /* We don't need to check for buffer overflow any more. */ ++ while ((c = *qpatnext++) != EOS) { ++ switch (c) { ++ case LBRACKET: ++ c = *qpatnext; ++ if (c == NOT) ++ ++qpatnext; ++ if (*qpatnext == EOS || ++ g_strchr(qpatnext+1, RBRACKET) == NULL) { ++ *bufnext++ = LBRACKET; ++ if (c == NOT) ++ --qpatnext; ++ break; ++ } ++ *bufnext++ = M_SET; ++ if (c == NOT) ++ *bufnext++ = M_NOT; ++ c = *qpatnext++; ++ do { ++ *bufnext++ = CHAR(c); ++ if (*qpatnext == RANGE && ++ (c = qpatnext[1]) != RBRACKET) { ++ *bufnext++ = M_RNG; ++ *bufnext++ = CHAR(c); ++ qpatnext += 2; ++ } ++ } while ((c = *qpatnext++) != RBRACKET); ++ pglob->gl_flags |= GLOB_MAGCHAR; ++ *bufnext++ = M_END; ++ break; ++ case QUESTION: ++ pglob->gl_flags |= GLOB_MAGCHAR; ++ *bufnext++ = M_ONE; ++ break; ++ case STAR: ++ pglob->gl_flags |= GLOB_MAGCHAR; ++ /* collapse adjacent stars to one, ++ * to avoid exponential behavior ++ */ ++ if (bufnext == patbuf || bufnext[-1] != M_ALL) ++ *bufnext++ = M_ALL; ++ break; ++ default: ++ *bufnext++ = CHAR(c); ++ break; ++ } ++ } ++ *bufnext = EOS; ++#ifdef DEBUG ++ qprintf("glob0:", patbuf); ++#endif ++ ++ if ((err = glob1(patbuf, pglob, limit)) != 0) ++ return(err); ++ ++ /* ++ * If there was no match we are going to append the pattern ++ * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified ++ * and the pattern did not contain any magic characters ++ * GLOB_NOMAGIC is there just for compatibility with csh. ++ */ ++ if (pglob->gl_pathc == oldpathc) { ++ if (((pglob->gl_flags & GLOB_NOCHECK) || ++ ((pglob->gl_flags & GLOB_NOMAGIC) && ++ !(pglob->gl_flags & GLOB_MAGCHAR)))) ++ return(globextend(pattern, pglob, limit)); ++ else ++ return(GLOB_NOMATCH); ++ } ++ if (!(pglob->gl_flags & GLOB_NOSORT)) ++ qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, ++ pglob->gl_pathc - oldpathc, sizeof(char *), compare); ++ return(0); ++} ++ ++static int ++compare(const void *p, const void *q) ++{ ++ return(strcmp(*(char **)p, *(char **)q)); ++} ++ ++static int ++glob1(Char *pattern, glob_t *pglob, size_t *limit) ++{ ++ Char pathbuf[MAXPATHLEN]; ++ ++ /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ ++ if (*pattern == EOS) ++ return(0); ++ return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, ++ pattern, pglob, limit)); ++} ++ ++/* ++ * The functions glob2 and glob3 are mutually recursive; there is one level ++ * of recursion for each segment in the pattern that contains one or more ++ * meta characters. ++ */ ++static int ++glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, ++ glob_t *pglob, size_t *limit) ++{ ++ struct stat sb; ++ Char *p, *q; ++ int anymeta; ++ ++ /* ++ * Loop over pattern segments until end of pattern or until ++ * segment with meta character found. ++ */ ++ for (anymeta = 0;;) { ++ if (*pattern == EOS) { /* End of pattern? */ ++ *pathend = EOS; ++ if (g_lstat(pathbuf, &sb, pglob)) ++ return(0); ++ ++ if (((pglob->gl_flags & GLOB_MARK) && ++ pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) ++ || (S_ISLNK(sb.st_mode) && ++ (g_stat(pathbuf, &sb, pglob) == 0) && ++ S_ISDIR(sb.st_mode)))) { ++ if (pathend + 1 > pathend_last) ++ return (GLOB_ABORTED); ++ *pathend++ = SEP; ++ *pathend = EOS; ++ } ++ ++pglob->gl_matchc; ++ return(globextend(pathbuf, pglob, limit)); ++ } ++ ++ /* Find end of next segment, copy tentatively to pathend. */ ++ q = pathend; ++ p = pattern; ++ while (*p != EOS && *p != SEP) { ++ if (ismeta(*p)) ++ anymeta = 1; ++ if (q + 1 > pathend_last) ++ return (GLOB_ABORTED); ++ *q++ = *p++; ++ } ++ ++ if (!anymeta) { /* No expansion, do next segment. */ ++ pathend = q; ++ pattern = p; ++ while (*pattern == SEP) { ++ if (pathend + 1 > pathend_last) ++ return (GLOB_ABORTED); ++ *pathend++ = *pattern++; ++ } ++ } else /* Need expansion, recurse. */ ++ return(glob3(pathbuf, pathend, pathend_last, pattern, p, ++ pglob, limit)); ++ } ++ /* NOTREACHED */ ++} ++ ++static int ++glob3(Char *pathbuf, Char *pathend, Char *pathend_last, ++ Char *pattern, Char *restpattern, ++ glob_t *pglob, size_t *limit) ++{ ++ struct dirent *dp; ++ DIR *dirp; ++ int err; ++ char buf[MAXPATHLEN]; ++ ++ /* ++ * The readdirfunc declaration can't be prototyped, because it is ++ * assigned, below, to two functions which are prototyped in glob.h ++ * and dirent.h as taking pointers to differently typed opaque ++ * structures. ++ */ ++ struct dirent *(*readdirfunc)(); ++ ++ if (pathend > pathend_last) ++ return (GLOB_ABORTED); ++ *pathend = EOS; ++ errno = 0; ++ ++ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { ++ /* TODO: don't call for ENOENT or ENOTDIR? */ ++ if (pglob->gl_errfunc) { ++ if (g_Ctoc(pathbuf, buf, sizeof(buf))) ++ return (GLOB_ABORTED); ++ if (pglob->gl_errfunc(buf, errno) || ++ pglob->gl_flags & GLOB_ERR) ++ return (GLOB_ABORTED); ++ } ++ return(0); ++ } ++ ++ err = 0; ++ ++ /* Search directory for matching names. */ ++ if (pglob->gl_flags & GLOB_ALTDIRFUNC) ++ readdirfunc = pglob->gl_readdir; ++ else ++ readdirfunc = readdir; ++ while ((dp = (*readdirfunc)(dirp))) { ++ char *sc; ++ Char *dc; ++ wchar_t wc; ++ size_t clen; ++ mbstate_t mbs; ++ ++ /* Initial DOT must be matched literally. */ ++ if (dp->d_name[0] == DOT && *pattern != DOT) ++ continue; ++ memset(&mbs, 0, sizeof(mbs)); ++ dc = pathend; ++ sc = dp->d_name; ++ while (dc < pathend_last) { ++ clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); ++ if (clen == (size_t)-1 || clen == (size_t)-2) { ++ wc = *sc; ++ clen = 1; ++ memset(&mbs, 0, sizeof(mbs)); ++ } ++ if ((*dc++ = wc) == EOS) ++ break; ++ sc += clen; ++ } ++ if (!match(pathend, pattern, restpattern)) { ++ *pathend = EOS; ++ continue; ++ } ++ err = glob2(pathbuf, --dc, pathend_last, restpattern, ++ pglob, limit); ++ if (err) ++ break; ++ } ++ ++ if (pglob->gl_flags & GLOB_ALTDIRFUNC) ++ (*pglob->gl_closedir)(dirp); ++ else ++ closedir(dirp); ++ return(err); ++} ++ ++ ++/* ++ * Extend the gl_pathv member of a glob_t structure to accomodate a new item, ++ * add the new item, and update gl_pathc. ++ * ++ * This assumes the BSD realloc, which only copies the block when its size ++ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic ++ * behavior. ++ * ++ * Return 0 if new item added, error code if memory couldn't be allocated. ++ * ++ * Invariant of the glob_t structure: ++ * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and ++ * gl_pathv points to (gl_offs + gl_pathc + 1) items. ++ */ ++static int ++globextend(const Char *path, glob_t *pglob, size_t *limit) ++{ ++ char **pathv; ++ size_t i, newsize, len; ++ char *copy; ++ const Char *p; ++ ++ if (*limit && pglob->gl_pathc > *limit) { ++ errno = 0; ++ return (GLOB_NOSPACE); ++ } ++ ++ newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); ++ pathv = pglob->gl_pathv ? ++ realloc((char *)pglob->gl_pathv, newsize) : ++ malloc(newsize); ++ if (pathv == NULL) { ++ if (pglob->gl_pathv) { ++ free(pglob->gl_pathv); ++ pglob->gl_pathv = NULL; ++ } ++ return(GLOB_NOSPACE); ++ } ++ ++ if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { ++ /* first time around -- clear initial gl_offs items */ ++ pathv += pglob->gl_offs; ++ for (i = pglob->gl_offs + 1; --i > 0; ) ++ *--pathv = NULL; ++ } ++ pglob->gl_pathv = pathv; ++ ++ for (p = path; *p++;) ++ continue; ++ len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ ++ if ((copy = malloc(len)) != NULL) { ++ if (g_Ctoc(path, copy, len)) { ++ free(copy); ++ return (GLOB_NOSPACE); ++ } ++ pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; ++ } ++ pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; ++ return(copy == NULL ? GLOB_NOSPACE : 0); ++} ++ ++/* ++ * pattern matching function for filenames. Each occurrence of the * ++ * pattern causes a recursion level. ++ */ ++static int ++match(Char *name, Char *pat, Char *patend) ++{ ++ int ok, negate_range; ++ Char c, k; ++ ++ while (pat < patend) { ++ c = *pat++; ++ switch (c & M_MASK) { ++ case M_ALL: ++ if (pat == patend) ++ return(1); ++ do ++ if (match(name, pat, patend)) ++ return(1); ++ while (*name++ != EOS); ++ return(0); ++ case M_ONE: ++ if (*name++ == EOS) ++ return(0); ++ break; ++ case M_SET: ++ ok = 0; ++ if ((k = *name++) == EOS) ++ return(0); ++ if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) ++ ++pat; ++ while (((c = *pat++) & M_MASK) != M_END) ++ if ((*pat & M_MASK) == M_RNG) { ++ if (CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1])) ok = 1; ++ pat += 2; ++ } else if (c == k) ++ ok = 1; ++ if (ok == negate_range) ++ return(0); ++ break; ++ default: ++ if (*name++ != c) ++ return(0); ++ break; ++ } ++ } ++ return(*name == EOS); ++} ++ ++/* Free allocated data belonging to a glob_t structure. */ ++void ++globfree(glob_t *pglob) ++{ ++ size_t i; ++ char **pp; ++ ++ if (pglob->gl_pathv != NULL) { ++ pp = pglob->gl_pathv + pglob->gl_offs; ++ for (i = pglob->gl_pathc; i--; ++pp) ++ if (*pp) ++ free(*pp); ++ free(pglob->gl_pathv); ++ pglob->gl_pathv = NULL; ++ } ++} ++ ++static DIR * ++g_opendir(Char *str, glob_t *pglob) ++{ ++ char buf[MAXPATHLEN]; ++ ++ if (!*str) ++ strcpy(buf, "."); ++ else { ++ if (g_Ctoc(str, buf, sizeof(buf))) ++ return (NULL); ++ } ++ ++ if (pglob->gl_flags & GLOB_ALTDIRFUNC) ++ return((*pglob->gl_opendir)(buf)); ++ ++ return(opendir(buf)); ++} ++ ++static int ++g_lstat(Char *fn, struct stat *sb, glob_t *pglob) ++{ ++ char buf[MAXPATHLEN]; ++ ++ if (g_Ctoc(fn, buf, sizeof(buf))) { ++ errno = ENAMETOOLONG; ++ return (-1); ++ } ++ if (pglob->gl_flags & GLOB_ALTDIRFUNC) ++ return((*pglob->gl_lstat)(buf, sb)); ++ return(lstat(buf, sb)); ++} ++ ++static int ++g_stat(Char *fn, struct stat *sb, glob_t *pglob) ++{ ++ char buf[MAXPATHLEN]; ++ ++ if (g_Ctoc(fn, buf, sizeof(buf))) { ++ errno = ENAMETOOLONG; ++ return (-1); ++ } ++ if (pglob->gl_flags & GLOB_ALTDIRFUNC) ++ return((*pglob->gl_stat)(buf, sb)); ++ return(stat(buf, sb)); ++} ++ ++static const Char * ++g_strchr(const Char *str, wchar_t ch) ++{ ++ ++ do { ++ if (*str == ch) ++ return (str); ++ } while (*str++); ++ return (NULL); ++} ++ ++static int ++g_Ctoc(const Char *str, char *buf, size_t len) ++{ ++ mbstate_t mbs; ++ size_t clen; ++ ++ memset(&mbs, 0, sizeof(mbs)); ++ while (len >= MB_CUR_MAX) { ++ clen = wcrtomb(buf, *str, &mbs); ++ if (clen == (size_t)-1) ++ return (1); ++ if (*str == L'\0') ++ return (0); ++ str++; ++ buf += clen; ++ len -= clen; ++ } ++ return (1); ++} ++ ++#ifdef DEBUG ++static void ++qprintf(const char *str, Char *s) ++{ ++ Char *p; ++ ++ (void)printf("%s:\n", str); ++ for (p = s; *p; p++) ++ (void)printf("%c", CHAR(*p)); ++ (void)printf("\n"); ++ for (p = s; *p; p++) ++ (void)printf("%c", *p & M_PROTECT ? '"' : ' '); ++ (void)printf("\n"); ++ for (p = s; *p; p++) ++ (void)printf("%c", ismeta(*p) ? '_' : ' '); ++ (void)printf("\n"); ++} ++#endif +diff --git a/glob.h b/glob.h +new file mode 100644 +index 0000000..351b6c4 +--- /dev/null ++++ b/glob.h +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (c) 1989, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * This code is derived from software contributed to Berkeley by ++ * Guido van Rossum. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * @(#)glob.h 8.1 (Berkeley) 6/2/93 ++ * $FreeBSD$ ++ */ ++ ++#ifndef _GLOB_H_ ++#define _GLOB_H_ ++ ++#include ++#include ++ ++#ifndef _SIZE_T_DECLARED ++typedef __size_t size_t; ++#define _SIZE_T_DECLARED ++#endif ++ ++struct stat; ++typedef struct { ++ size_t gl_pathc; /* Count of total paths so far. */ ++ size_t gl_matchc; /* Count of paths matching pattern. */ ++ size_t gl_offs; /* Reserved at beginning of gl_pathv. */ ++ int gl_flags; /* Copy of flags parameter to glob. */ ++ char **gl_pathv; /* List of paths matching pattern. */ ++ /* Copy of errfunc parameter to glob. */ ++ int (*gl_errfunc)(const char *, int); ++ ++ /* ++ * Alternate filesystem access methods for glob; replacement ++ * versions of closedir(3), readdir(3), opendir(3), stat(2) ++ * and lstat(2). ++ */ ++ void (*gl_closedir)(void *); ++ struct dirent *(*gl_readdir)(void *); ++ void *(*gl_opendir)(const char *); ++ int (*gl_lstat)(const char *, struct stat *); ++ int (*gl_stat)(const char *, struct stat *); ++} glob_t; ++ ++#if __POSIX_VISIBLE >= 199209 ++/* Believed to have been introduced in 1003.2-1992 */ ++#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ ++#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ ++#define GLOB_ERR 0x0004 /* Return on error. */ ++#define GLOB_MARK 0x0008 /* Append / to matching directories. */ ++#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ ++#define GLOB_NOSORT 0x0020 /* Don't sort. */ ++#define GLOB_NOESCAPE 0x2000 /* Disable backslash escaping. */ ++ ++/* Error values returned by glob(3) */ ++#define GLOB_NOSPACE (-1) /* Malloc call failed. */ ++#define GLOB_ABORTED (-2) /* Unignored error. */ ++#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK was not set. */ ++#define GLOB_NOSYS (-4) /* Obsolete: source comptability only. */ ++#endif /* __POSIX_VISIBLE >= 199209 */ ++ ++#if __BSD_VISIBLE ++#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ ++#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ ++#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ ++#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ ++#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ ++#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ ++#define GLOB_LIMIT 0x1000 /* limit number of returned paths */ ++ ++/* source compatibility, these are the old names */ ++#define GLOB_MAXPATH GLOB_LIMIT ++#define GLOB_ABEND GLOB_ABORTED ++#endif /* __BSD_VISIBLE */ ++ ++__BEGIN_DECLS ++int glob(const char *, int, int (*)(const char *, int), glob_t *); ++void globfree(glob_t *); ++__END_DECLS ++ ++#endif /* !_GLOB_H_ */ +-- +1.9.1 + From ec3eac6d6df3ce30d5071947b752ab6b4bf8c6bd Mon Sep 17 00:00:00 2001 From: Elena Pereira Date: Mon, 13 Nov 2017 16:04:30 -0500 Subject: [PATCH 21/21] Correct references to local files --- pythonforandroid/recipes/levenshtein/__init__.py | 6 +++--- pythonforandroid/recipes/lxml/__init__.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pythonforandroid/recipes/levenshtein/__init__.py b/pythonforandroid/recipes/levenshtein/__init__.py index 4b0ed418dc..77fd404559 100644 --- a/pythonforandroid/recipes/levenshtein/__init__.py +++ b/pythonforandroid/recipes/levenshtein/__init__.py @@ -11,10 +11,10 @@ class LevenshteinRecipe(CompiledComponentsPythonRecipe): def get_recipe_env(self, arch): env = super(LevenshteinRecipe, self).get_recipe_env(arch) - bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" - bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" + libxslt_recipe = Recipe.get_recipe('libxslt', self.ctx) + libxml2_recipe = Recipe.get_recipe('libxml2', self.ctx) targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) - env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) + env['CC'] += " -I%s/include -I%s -I%s" % (libxml2_recipe, libxslt_recipe, targetpython) env['LDSHARED'] = '%s -nostartfiles -shared -fPIC -lpython2.7' % env['CC'] return env diff --git a/pythonforandroid/recipes/lxml/__init__.py b/pythonforandroid/recipes/lxml/__init__.py index 337618b4d7..92704ee53c 100644 --- a/pythonforandroid/recipes/lxml/__init__.py +++ b/pythonforandroid/recipes/lxml/__init__.py @@ -26,10 +26,10 @@ def build_arch(self, arch): def get_recipe_env(self, arch): env = super(LXMLRecipe, self).get_recipe_env(arch) - bxml = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxml2/armeabi/libxml2/" - bxsl = "/home/zgoldberg/.local/share/python-for-android/build/other_builds/libxslt/armeabi/libxslt" + libxslt_recipe = Recipe.get_recipe('libxslt', self.ctx) + libxml2_recipe = Recipe.get_recipe('libxml2', self.ctx) targetpython = "%s/include/python2.7/" % dirname(dirname(self.ctx.hostpython)) - env['CC'] += " -I%s/include -I%s -I%s" % (bxml, bxsl, targetpython) + env['CC'] += " -I%s/include -I%s -I%s" % (libxml2_recipe, libxslt_recipe, targetpython) env['LDSHARED'] = '%s -nostartfiles -shared -fPIC -lpython2.7' % env['CC'] return env