Imported Upstream version 2.1.3
authorJelmer Vernooij <jelmer@debian.org>
Sat, 19 Sep 2015 02:42:31 +0000 (02:42 +0000)
committerJelmer Vernooij <jelmer@debian.org>
Sat, 19 Sep 2015 02:42:31 +0000 (02:42 +0000)
119 files changed:
ABI/pytalloc-util-2.1.3.sigs [new file with mode: 0644]
ABI/talloc-2.1.3.sigs [new file with mode: 0644]
buildtools/bin/waf
buildtools/examples/run_on_target.py [new file with mode: 0755]
buildtools/update-waf.sh [deleted file]
buildtools/wafsamba/samba3.py
buildtools/wafsamba/samba_autoconf.py
buildtools/wafsamba/samba_autoproto.py
buildtools/wafsamba/samba_bundled.py
buildtools/wafsamba/samba_conftests.py
buildtools/wafsamba/samba_cross.py
buildtools/wafsamba/samba_deps.py
buildtools/wafsamba/samba_dist.py
buildtools/wafsamba/samba_git.py [new file with mode: 0644]
buildtools/wafsamba/samba_install.py
buildtools/wafsamba/samba_optimisation.py
buildtools/wafsamba/samba_patterns.py
buildtools/wafsamba/samba_pidl.py
buildtools/wafsamba/samba_python.py
buildtools/wafsamba/samba_utils.py
buildtools/wafsamba/samba_version.py
buildtools/wafsamba/wafsamba.py
buildtools/wafsamba/wscript
doc/mainpage.dox
doc/tutorial_introduction.dox
doc/tutorial_threads.dox [new file with mode: 0644]
lib/replace/replace.c
lib/replace/system/threads.h
lib/replace/test/os2_delete.c
lib/replace/test/testsuite.c
lib/replace/wscript
man/talloc.3.xml
pytalloc-util.pc.in
pytalloc.c
pytalloc.h
pytalloc_guide.txt
pytalloc_util.c
talloc.i [deleted file]
talloc_guide.txt
test_pytalloc.c [new file with mode: 0644]
test_pytalloc.py [new file with mode: 0644]
testsuite.c
third_party/waf/wafadmin/3rdparty/ParallelDebug.py [moved from buildtools/wafadmin/3rdparty/ParallelDebug.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/batched_cc.py [moved from buildtools/wafadmin/3rdparty/batched_cc.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/boost.py [moved from buildtools/wafadmin/3rdparty/boost.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/build_file_tracker.py [new file with mode: 0644]
third_party/waf/wafadmin/3rdparty/fluid.py [moved from buildtools/wafadmin/3rdparty/fluid.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/gccdeps.py [moved from buildtools/wafadmin/3rdparty/gccdeps.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/go.py [moved from buildtools/wafadmin/3rdparty/go.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/lru_cache.py [moved from buildtools/wafadmin/3rdparty/lru_cache.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/paranoid.py [moved from buildtools/wafadmin/3rdparty/paranoid.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/prefork.py [new file with mode: 0755]
third_party/waf/wafadmin/3rdparty/swig.py [moved from buildtools/wafadmin/3rdparty/swig.py with 99% similarity]
third_party/waf/wafadmin/3rdparty/valadoc.py [moved from buildtools/wafadmin/3rdparty/valadoc.py with 99% similarity]
third_party/waf/wafadmin/Build.py [moved from buildtools/wafadmin/Build.py with 99% similarity]
third_party/waf/wafadmin/Configure.py [moved from buildtools/wafadmin/Configure.py with 99% similarity]
third_party/waf/wafadmin/Constants.py [moved from buildtools/wafadmin/Constants.py with 99% similarity]
third_party/waf/wafadmin/Environment.py [moved from buildtools/wafadmin/Environment.py with 99% similarity]
third_party/waf/wafadmin/Logs.py [moved from buildtools/wafadmin/Logs.py with 99% similarity]
third_party/waf/wafadmin/Node.py [moved from buildtools/wafadmin/Node.py with 99% similarity]
third_party/waf/wafadmin/Options.py [moved from buildtools/wafadmin/Options.py with 99% similarity]
third_party/waf/wafadmin/Runner.py [moved from buildtools/wafadmin/Runner.py with 99% similarity]
third_party/waf/wafadmin/Scripting.py [moved from buildtools/wafadmin/Scripting.py with 99% similarity]
third_party/waf/wafadmin/Task.py [moved from buildtools/wafadmin/Task.py with 99% similarity]
third_party/waf/wafadmin/TaskGen.py [moved from buildtools/wafadmin/TaskGen.py with 98% similarity]
third_party/waf/wafadmin/Tools/__init__.py [moved from buildtools/wafadmin/Tools/__init__.py with 98% similarity]
third_party/waf/wafadmin/Tools/ar.py [moved from buildtools/wafadmin/Tools/ar.py with 99% similarity]
third_party/waf/wafadmin/Tools/bison.py [moved from buildtools/wafadmin/Tools/bison.py with 99% similarity]
third_party/waf/wafadmin/Tools/cc.py [moved from buildtools/wafadmin/Tools/cc.py with 99% similarity]
third_party/waf/wafadmin/Tools/ccroot.py [moved from buildtools/wafadmin/Tools/ccroot.py with 99% similarity]
third_party/waf/wafadmin/Tools/compiler_cc.py [moved from buildtools/wafadmin/Tools/compiler_cc.py with 99% similarity]
third_party/waf/wafadmin/Tools/compiler_cxx.py [moved from buildtools/wafadmin/Tools/compiler_cxx.py with 99% similarity]
third_party/waf/wafadmin/Tools/compiler_d.py [moved from buildtools/wafadmin/Tools/compiler_d.py with 99% similarity]
third_party/waf/wafadmin/Tools/config_c.py [moved from buildtools/wafadmin/Tools/config_c.py with 99% similarity]
third_party/waf/wafadmin/Tools/cs.py [moved from buildtools/wafadmin/Tools/cs.py with 99% similarity]
third_party/waf/wafadmin/Tools/cxx.py [moved from buildtools/wafadmin/Tools/cxx.py with 99% similarity]
third_party/waf/wafadmin/Tools/d.py [moved from buildtools/wafadmin/Tools/d.py with 99% similarity]
third_party/waf/wafadmin/Tools/dbus.py [moved from buildtools/wafadmin/Tools/dbus.py with 99% similarity]
third_party/waf/wafadmin/Tools/dmd.py [moved from buildtools/wafadmin/Tools/dmd.py with 99% similarity]
third_party/waf/wafadmin/Tools/flex.py [moved from buildtools/wafadmin/Tools/flex.py with 99% similarity]
third_party/waf/wafadmin/Tools/gas.py [moved from buildtools/wafadmin/Tools/gas.py with 99% similarity]
third_party/waf/wafadmin/Tools/gcc.py [moved from buildtools/wafadmin/Tools/gcc.py with 99% similarity]
third_party/waf/wafadmin/Tools/gdc.py [moved from buildtools/wafadmin/Tools/gdc.py with 99% similarity]
third_party/waf/wafadmin/Tools/glib2.py [moved from buildtools/wafadmin/Tools/glib2.py with 99% similarity]
third_party/waf/wafadmin/Tools/gnome.py [moved from buildtools/wafadmin/Tools/gnome.py with 99% similarity]
third_party/waf/wafadmin/Tools/gnu_dirs.py [moved from buildtools/wafadmin/Tools/gnu_dirs.py with 99% similarity]
third_party/waf/wafadmin/Tools/gob2.py [moved from buildtools/wafadmin/Tools/gob2.py with 99% similarity]
third_party/waf/wafadmin/Tools/gxx.py [moved from buildtools/wafadmin/Tools/gxx.py with 99% similarity]
third_party/waf/wafadmin/Tools/icc.py [moved from buildtools/wafadmin/Tools/icc.py with 100% similarity]
third_party/waf/wafadmin/Tools/icpc.py [moved from buildtools/wafadmin/Tools/icpc.py with 100% similarity]
third_party/waf/wafadmin/Tools/intltool.py [moved from buildtools/wafadmin/Tools/intltool.py with 99% similarity]
third_party/waf/wafadmin/Tools/javaw.py [moved from buildtools/wafadmin/Tools/javaw.py with 99% similarity]
third_party/waf/wafadmin/Tools/kde4.py [moved from buildtools/wafadmin/Tools/kde4.py with 99% similarity]
third_party/waf/wafadmin/Tools/libtool.py [moved from buildtools/wafadmin/Tools/libtool.py with 99% similarity]
third_party/waf/wafadmin/Tools/lua.py [moved from buildtools/wafadmin/Tools/lua.py with 99% similarity]
third_party/waf/wafadmin/Tools/misc.py [moved from buildtools/wafadmin/Tools/misc.py with 99% similarity]
third_party/waf/wafadmin/Tools/msvc.py [moved from buildtools/wafadmin/Tools/msvc.py with 99% similarity]
third_party/waf/wafadmin/Tools/nasm.py [moved from buildtools/wafadmin/Tools/nasm.py with 95% similarity]
third_party/waf/wafadmin/Tools/ocaml.py [moved from buildtools/wafadmin/Tools/ocaml.py with 99% similarity]
third_party/waf/wafadmin/Tools/osx.py [moved from buildtools/wafadmin/Tools/osx.py with 99% similarity]
third_party/waf/wafadmin/Tools/perl.py [moved from buildtools/wafadmin/Tools/perl.py with 99% similarity]
third_party/waf/wafadmin/Tools/preproc.py [moved from buildtools/wafadmin/Tools/preproc.py with 99% similarity]
third_party/waf/wafadmin/Tools/python.py [moved from buildtools/wafadmin/Tools/python.py with 97% similarity]
third_party/waf/wafadmin/Tools/qt4.py [moved from buildtools/wafadmin/Tools/qt4.py with 99% similarity]
third_party/waf/wafadmin/Tools/ruby.py [moved from buildtools/wafadmin/Tools/ruby.py with 99% similarity]
third_party/waf/wafadmin/Tools/suncc.py [moved from buildtools/wafadmin/Tools/suncc.py with 100% similarity]
third_party/waf/wafadmin/Tools/suncxx.py [moved from buildtools/wafadmin/Tools/suncxx.py with 100% similarity]
third_party/waf/wafadmin/Tools/tex.py [moved from buildtools/wafadmin/Tools/tex.py with 99% similarity]
third_party/waf/wafadmin/Tools/unittestw.py [moved from buildtools/wafadmin/Tools/unittestw.py with 99% similarity]
third_party/waf/wafadmin/Tools/vala.py [moved from buildtools/wafadmin/Tools/vala.py with 99% similarity]
third_party/waf/wafadmin/Tools/winres.py [moved from buildtools/wafadmin/Tools/winres.py with 99% similarity]
third_party/waf/wafadmin/Tools/xlc.py [moved from buildtools/wafadmin/Tools/xlc.py with 100% similarity]
third_party/waf/wafadmin/Tools/xlcxx.py [moved from buildtools/wafadmin/Tools/xlcxx.py with 100% similarity]
third_party/waf/wafadmin/Utils.py [moved from buildtools/wafadmin/Utils.py with 99% similarity]
third_party/waf/wafadmin/__init__.py [moved from buildtools/wafadmin/__init__.py with 100% similarity]
third_party/waf/wafadmin/ansiterm.py [moved from buildtools/wafadmin/ansiterm.py with 99% similarity]
third_party/waf/wafadmin/pproc.py [moved from buildtools/wafadmin/pproc.py with 99% similarity]
third_party/waf/wafadmin/py3kfixes.py [moved from buildtools/wafadmin/py3kfixes.py with 99% similarity]
wscript

diff --git a/ABI/pytalloc-util-2.1.3.sigs b/ABI/pytalloc-util-2.1.3.sigs
new file mode 100644 (file)
index 0000000..961c1a8
--- /dev/null
@@ -0,0 +1,6 @@
+pytalloc_CObject_FromTallocPtr: PyObject *(void *)
+pytalloc_Check: int (PyObject *)
+pytalloc_GetObjectType: PyTypeObject *(void)
+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
+pytalloc_steal: PyObject *(PyTypeObject *, void *)
+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/ABI/talloc-2.1.3.sigs b/ABI/talloc-2.1.3.sigs
new file mode 100644 (file)
index 0000000..eae12cc
--- /dev/null
@@ -0,0 +1,64 @@
+_talloc: void *(const void *, size_t)
+_talloc_array: void *(const void *, size_t, unsigned int, const char *)
+_talloc_free: int (void *, const char *)
+_talloc_get_type_abort: void *(const void *, const char *, const char *)
+_talloc_memdup: void *(const void *, const void *, size_t, const char *)
+_talloc_move: void *(const void *, const void *)
+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t)
+_talloc_realloc: void *(const void *, void *, size_t, const char *)
+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *)
+_talloc_reference_loc: void *(const void *, const void *, const char *)
+_talloc_set_destructor: void (const void *, int (*)(void *))
+_talloc_steal_loc: void *(const void *, const void *, const char *)
+_talloc_zero: void *(const void *, size_t, const char *)
+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *)
+talloc_asprintf: char *(const void *, const char *, ...)
+talloc_asprintf_append: char *(char *, const char *, ...)
+talloc_asprintf_append_buffer: char *(char *, const char *, ...)
+talloc_autofree_context: void *(void)
+talloc_check_name: void *(const void *, const char *)
+talloc_disable_null_tracking: void (void)
+talloc_enable_leak_report: void (void)
+talloc_enable_leak_report_full: void (void)
+talloc_enable_null_tracking: void (void)
+talloc_enable_null_tracking_no_autofree: void (void)
+talloc_find_parent_byname: void *(const void *, const char *)
+talloc_free_children: void (void *)
+talloc_get_name: const char *(const void *)
+talloc_get_size: size_t (const void *)
+talloc_increase_ref_count: int (const void *)
+talloc_init: void *(const char *, ...)
+talloc_is_parent: int (const void *, const void *)
+talloc_named: void *(const void *, size_t, const char *, ...)
+talloc_named_const: void *(const void *, size_t, const char *)
+talloc_parent: void *(const void *)
+talloc_parent_name: const char *(const void *)
+talloc_pool: void *(const void *, size_t)
+talloc_realloc_fn: void *(const void *, void *, size_t)
+talloc_reference_count: size_t (const void *)
+talloc_reparent: void *(const void *, const void *, const void *)
+talloc_report: void (const void *, FILE *)
+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *)
+talloc_report_depth_file: void (const void *, int, int, FILE *)
+talloc_report_full: void (const void *, FILE *)
+talloc_set_abort_fn: void (void (*)(const char *))
+talloc_set_log_fn: void (void (*)(const char *))
+talloc_set_log_stderr: void (void)
+talloc_set_memlimit: int (const void *, size_t)
+talloc_set_name: const char *(const void *, const char *, ...)
+talloc_set_name_const: void (const void *, const char *)
+talloc_show_parents: void (const void *, FILE *)
+talloc_strdup: char *(const void *, const char *)
+talloc_strdup_append: char *(char *, const char *)
+talloc_strdup_append_buffer: char *(char *, const char *)
+talloc_strndup: char *(const void *, const char *, size_t)
+talloc_strndup_append: char *(char *, const char *, size_t)
+talloc_strndup_append_buffer: char *(char *, const char *, size_t)
+talloc_total_blocks: size_t (const void *)
+talloc_total_size: size_t (const void *)
+talloc_unlink: int (const void *, void *)
+talloc_vasprintf: char *(const void *, const char *, va_list)
+talloc_vasprintf_append: char *(char *, const char *, va_list)
+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list)
+talloc_version_major: int (void)
+talloc_version_minor: int (void)
index db6a7d3386a137602901b9a55560b469f76d5e35..1b0f4662a56d7c44b5bb2215724d7af63a28018e 100755 (executable)
@@ -63,7 +63,7 @@ def test(dir):
        except OSError: pass
 
 def find_lib():
-       return os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+       return os.path.abspath(os.path.join(os.path.dirname(__file__), '../../third_party/waf'))
 
 wafdir = find_lib()
 w = join(wafdir, 'wafadmin')
diff --git a/buildtools/examples/run_on_target.py b/buildtools/examples/run_on_target.py
new file mode 100755 (executable)
index 0000000..8322759
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+
+#
+# Sample run-on-target script
+# This is a script that can be used as cross-execute parameter to samba
+# configuration process, running the command on a remote target for which
+# the cross-compiled configure test was compiled.
+#
+# To use:
+# ./configure \
+# --cross-compile \
+# '--cross-execute=./buildtools/example/run_on_target.py --host=<host>'
+#
+# A more elaborate example:
+# ./configure \
+# --cross-compile \
+# '--cross-execute=./buildtools/example/run_on_target.py --host=<host> --user=<user> "--ssh=ssh -i <some key file>" --destdir=/path/to/dir'
+#
+# Typically this is to be used also with --cross-answers, so that the
+# cross answers file gets built and further builds can be made without
+# the help of a remote target.
+#
+# The following assumptions are made:
+# 1. rsync is available on build machine and target machine
+# 2. A running ssh service on target machine with password-less shell login
+# 3. A directory writable by the password-less login user
+# 4. The tests on the target can run and provide reliable results
+#    from the login account's home directory. This is significant
+#    for example in locking tests which
+#    create files in the current directory. As a workaround to this
+#    assumption, the TESTDIR environment variable can be set on the target
+#    (using ssh command line or server config) and the tests shall
+#    chdir to that directory.
+#
+
+import sys
+import os
+import subprocess
+from optparse import OptionParser
+
+# those are defaults, but can be overidden using command line
+SSH = 'ssh'
+USER = None
+HOST = 'localhost'
+
+
+def xfer_files(ssh, srcdir, host, user, targ_destdir):
+    """Transfer executable files to target
+
+    Use rsync to copy the directory containing program to run
+    INTO a destination directory on the target. An exact copy
+    of the source directory is created on the target machine,
+    possibly deleting files on the target machine which do not
+    exist on the source directory.
+
+    The idea is that the test may include files in addition to
+    the compiled binary, and all of those files reside alongside
+    the binary in a source directory.
+
+    For example, if the test to run is /foo/bar/test and the
+    destination directory on the target is /tbaz, then /tbaz/bar
+    on the target shall be an exact copy of /foo/bar on the source,
+    including deletion of files inside /tbaz/bar which do not exist
+    on the source.
+    """
+
+    userhost = host
+    if user:
+        userhost = '%s@%s' % (user, host)
+
+    cmd = 'rsync --verbose -rl --ignore-times --delete -e "%s" %s %s:%s/' % \
+          (ssh, srcdir, userhost, targ_destdir)
+    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+    (out, err) = p.communicate()
+    if p.returncode != 0:
+        raise Exception('failed syncing files\n stdout:\n%s\nstderr:%s\n'
+                        % (out, err))
+
+
+def exec_remote(ssh, host, user, destdir, targdir, prog, args):
+    """Run a test on the target
+
+    Using password-less ssh, run the compiled binary on the target.
+
+    An assumption is that there's no need to cd into the target dir,
+    same as there's no need to do it on a native build.
+    """
+    userhost = host
+    if user:
+        userhost = '%s@%s' % (user, host)
+
+    cmd = '%s %s %s/%s/%s' % (ssh, userhost, destdir, targdir, prog)
+    if args:
+        cmd = cmd + ' ' + ' '.join(args)
+    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+    (out, err) = p.communicate()
+    return (p.returncode, out)
+
+
+def main(argv):
+    usage = "usage: %prog [options] <prog> [args]"
+    parser = OptionParser(usage)
+
+    parser.add_option('--ssh', help="SSH client and additional flags",
+                      default=SSH)
+    parser.add_option('--host', help="target host name or IP address",
+                      default=HOST)
+    parser.add_option('--user', help="login user on target",
+                      default=USER)
+    parser.add_option('--destdir', help="work directory on target",
+                      default='~')
+
+    (options, args) = parser.parse_args(argv)
+    if len(args) < 1:
+        parser.error("please supply test program to run")
+
+    progpath = args[0]
+
+    # assume that a test that was not compiled fails (e.g. getconf)
+    if progpath[0] != '/':
+        return (1, "")
+
+    progdir = os.path.dirname(progpath)
+    prog = os.path.basename(progpath)
+    targ_progdir = os.path.basename(progdir)
+
+    xfer_files(
+        options.ssh,
+        progdir,
+        options.host,
+        options.user,
+        options.destdir)
+
+    (rc, out) = exec_remote(options.ssh,
+                            options.host,
+                            options.user,
+                            options.destdir,
+                            targ_progdir,
+                            prog, args[1:])
+    return (rc, out)
+
+
+if __name__ == '__main__':
+    (rc, out) = main(sys.argv[1:])
+    sys.stdout.write(out)
+    sys.exit(rc)
diff --git a/buildtools/update-waf.sh b/buildtools/update-waf.sh
deleted file mode 100755 (executable)
index 277111f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-# Update our copy of waf
-
-TARGETDIR="`dirname $0`"
-WORKDIR="`mktemp -d -t update-waf-XXXXXX`"
-
-mkdir -p "$WORKDIR"
-
-git clone https://code.google.com/p/waf.waf15/ "$WORKDIR"
-
-rsync -C -avz --delete "$WORKDIR/wafadmin/" "$TARGETDIR/wafadmin/"
-
-rm -rf "$WORKDIR"
index ffe678416edfb457a92b200530c9b3c2bc7193e0..6d06fd929a1ca7aa8b2c375774c251a924f3a737 100644 (file)
@@ -62,7 +62,7 @@ def s3_fix_kwargs(bld, kwargs):
     s3reldir = os_path_relpath(s3dir, bld.curdir)
 
     # the extra_includes list is relative to the source3 directory
-    extra_includes = [ '.', 'include', 'lib', '../lib/tdb_compat' ]
+    extra_includes = [ '.', 'include', 'lib' ]
     # local heimdal paths only included when USING_SYSTEM_KRB5 is not set
     if not bld.CONFIG_SET("USING_SYSTEM_KRB5"):
         extra_includes += [ '../source4/heimdal/lib/com_err',
index 905adc7df6413e0bf8bf1d9bc0daa0a482bb9884..c5f132cf17b48a3483342671cba79727bc3f4c91 100644 (file)
@@ -229,7 +229,18 @@ def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False):
                               headers=headers,
                               msg='Checking for declaration of %s' % v,
                               always=always):
-            ret = False
+            if not CHECK_CODE(conf,
+                      '''
+                      return (int)%s;
+                      ''' % (v),
+                      execute=False,
+                      link=False,
+                      msg='Checking for declaration of %s (as enum)' % v,
+                      local_include=False,
+                      headers=headers,
+                      define=define,
+                      always=always):
+                ret = False
     return ret
 
 
@@ -846,3 +857,7 @@ def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
     if not sys.platform.startswith("openbsd") and conf.env.undefined_ignore_ldflags == []:
         if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
             conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']
+
+@conf
+def CHECK_CFG(self, *k, **kw):
+    return self.check_cfg(*k, **kw)
index 2d8ea546ab2a594ddb69a8cf179dbb04c27321b6..bad627aa4dec33ec514fc7daa6bf774bb161c77d 100644 (file)
@@ -13,7 +13,7 @@ def SAMBA_AUTOPROTO(bld, header, source):
         name = name,
         source = source,
         target = header,
-        on_results=True,
+        update_outputs=True,
         ext_out='.c',
         before ='cc',
         rule = '${PERL} "${SCRIPT}/mkproto.pl" --srcdir=.. --builddir=. --public=/dev/null --private="${TGT}" ${SRC}'
index 515590fb01468a1d9218705d8644e661487f205d..c8bfcd23cfd8bcf1f9925c27ee090c33ac7fc49b 100644 (file)
@@ -190,7 +190,7 @@ def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0',
         pkg = libname
 
     # try pkgconfig first
-    if (conf.check_cfg(package=pkg,
+    if (conf.CHECK_CFG(package=pkg,
                       args='"%s >= %s" --cflags --libs' % (pkg, minversion),
                       msg=msg, uselib_store=uselib_store) and
         check_functions_headers_code()):
index 1afc6c94fbe817d89043f2f806208995f11efcca..96fead5812833fe80e42d852c57ccf66cec04712 100644 (file)
@@ -565,7 +565,6 @@ def samba_config_c_parse_flags(line1, uselib, env):
         # bugs in the real parse_flags() function.
         #
         if x == '-Wl,-rpath' or x == '-Wl,-R':
-            linkflags.remove(x)
             x = lst1.pop(0)
             if x.startswith('-Wl,'):
                 rpath = x[4:]
index 3838e34ec48244d093e48c17f5ebdc2d302f45f4..ed3af1e7db1d371b20a374ed0f6839f6c28c77ea 100644 (file)
@@ -2,11 +2,12 @@
 
 import Utils, Logs, sys, os, Options, re
 from Configure import conf
+import shlex
 
 real_Popen = None
 
 ANSWER_UNKNOWN = (254, "")
-ANSWER_FAIL    = (255, "")
+ANSWER_NO      = (1, "")
 ANSWER_OK      = (0, "")
 
 cross_answers_incomplete = False
@@ -19,15 +20,27 @@ def add_answer(ca_file, msg, answer):
     except:
         Logs.error("Unable to open cross-answers file %s" % ca_file)
         sys.exit(1)
+    (retcode, retstring) = answer
+    # if retstring is more than one line then we probably
+    # don't care about its actual content (the tests should
+    # yield one-line output in order to comply with the cross-answer
+    # format)
+    retstring = retstring.strip()
+    if len(retstring.split('\n')) > 1:
+        retstring = ''
+    answer = (retcode, retstring)
+
     if answer == ANSWER_OK:
         f.write('%s: OK\n' % msg)
     elif answer == ANSWER_UNKNOWN:
         f.write('%s: UNKNOWN\n' % msg)
-    elif answer == ANSWER_FAIL:
-        f.write('%s: FAIL\n' % msg)
+    elif answer == ANSWER_NO:
+        f.write('%s: NO\n' % msg)
     else:
-        (retcode, retstring) = answer
-        f.write('%s: (%d, "%s")' % (msg, retcode, retstring))
+        if retcode == 0:
+            f.write('%s: "%s"\n' % (msg, retstring))
+        else:
+            f.write('%s: (%d, "%s")\n' % (msg, retcode, retstring))
     f.close()
 
 
@@ -36,14 +49,13 @@ def cross_answer(ca_file, msg):
     try:
         f = open(ca_file, 'r')
     except:
-        add_answer(ca_file, msg, ANSWER_UNKNOWN)
         return ANSWER_UNKNOWN
     for line in f:
         line = line.strip()
         if line == '' or line[0] == '#':
             continue
         if line.find(':') != -1:
-            a = line.split(':')
+            a = line.split(':', 1)
             thismsg = a[0].strip()
             if thismsg != msg:
                 continue
@@ -56,10 +68,12 @@ def cross_answer(ca_file, msg):
                 return ANSWER_UNKNOWN
             elif ans == "FAIL" or ans == "NO":
                 f.close()
-                return ANSWER_FAIL
+                return ANSWER_NO
             elif ans[0] == '"':
+                f.close()
                 return (0, ans.strip('"'))
             elif ans[0] == "'":
+                f.close()
                 return (0, ans.strip("'"))
             else:
                 m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans)
@@ -69,7 +83,6 @@ def cross_answer(ca_file, msg):
                 else:
                     raise Utils.WafError("Bad answer format '%s' in %s" % (line, ca_file))
     f.close()
-    add_answer(ca_file, msg, ANSWER_UNKNOWN)
     return ANSWER_UNKNOWN
 
 
@@ -77,24 +90,47 @@ class cross_Popen(Utils.pproc.Popen):
     '''cross-compilation wrapper for Popen'''
     def __init__(*k, **kw):
         (obj, args) = k
-
-        if '--cross-execute' in args:
-            # when --cross-execute is set, then change the arguments
-            # to use the cross emulator
-            i = args.index('--cross-execute')
-            newargs = args[i+1].split()
-            newargs.extend(args[0:i])
-            args = newargs
-        elif '--cross-answers' in args:
+        use_answers = False
+        ans = ANSWER_UNKNOWN
+
+        # Three possibilities:
+        #   1. Only cross-answers - try the cross-answers file, and if
+        #      there's no corresponding answer, add to the file and mark
+        #      the configure process as unfinished.
+        #   2. Only cross-execute - get the answer from cross-execute
+        #   3. Both - try the cross-answers file, and if there is no
+        #      corresponding answer - use cross-execute to get an answer,
+        #       and add that answer to the file.
+        if '--cross-answers' in args:
             # when --cross-answers is set, then change the arguments
             # to use the cross answers if available
+            use_answers = True
             i = args.index('--cross-answers')
             ca_file = args[i+1]
             msg     = args[i+2]
             ans = cross_answer(ca_file, msg)
+
+        if '--cross-execute' in args and ans == ANSWER_UNKNOWN:
+            # when --cross-execute is set, then change the arguments
+            # to use the cross emulator
+            i = args.index('--cross-execute')
+            newargs = shlex.split(args[i+1])
+            newargs.extend(args[0:i])
+            if use_answers:
+                p = real_Popen(newargs,
+                               stdout=Utils.pproc.PIPE,
+                               stderr=Utils.pproc.PIPE)
+                ce_out, ce_err = p.communicate()
+                ans = (p.returncode, ce_out)
+                add_answer(ca_file, msg, ans)
+            else:
+                args = newargs
+
+        if use_answers:
             if ans == ANSWER_UNKNOWN:
                 global cross_answers_incomplete
                 cross_answers_incomplete = True
+                add_answer(ca_file, msg, ans)
             (retcode, retstring) = ans
             args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)]
         real_Popen.__init__(*(obj, args), **kw)
@@ -115,7 +151,8 @@ def SAMBA_CROSS_ARGS(conf, msg=None):
 
     if conf.env.CROSS_EXECUTE:
         ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE])
-    elif conf.env.CROSS_ANSWERS:
+
+    if conf.env.CROSS_ANSWERS:
         if msg is None:
             raise Utils.WafError("Cannot have NULL msg in cross-answers")
         ret.extend(['--cross-answers', os.path.join(Options.launch_dir, conf.env.CROSS_ANSWERS), msg])
index 3be99565a664aa55359b57e5fb52c8fa4a8dbee5..d252dc4eef8bb973920cc4de64e79c9a99af2b85 100644 (file)
@@ -964,7 +964,8 @@ savedeps_version = 3
 savedeps_inputs  = ['samba_deps', 'samba_includes', 'local_include', 'local_include_first', 'samba_cflags',
                     'source', 'grouping_library', 'samba_ldflags', 'allow_undefined_symbols',
                     'use_global_deps', 'global_include' ]
-savedeps_outputs = ['uselib', 'uselib_local', 'add_objects', 'includes', 'ccflags', 'ldflags', 'samba_deps_extended']
+savedeps_outputs = ['uselib', 'uselib_local', 'add_objects', 'includes',
+                    'ccflags', 'ldflags', 'samba_deps_extended', 'final_libs']
 savedeps_outenv  = ['INC_PATHS']
 savedeps_envvars = ['NONSHARED_BINARIES', 'GLOBAL_DEPENDENCIES', 'EXTRA_CFLAGS', 'EXTRA_LDFLAGS', 'EXTRA_INCLUDES' ]
 savedeps_caches  = ['GLOBAL_DEPENDENCIES', 'TARGET_TYPE', 'INIT_FUNCTIONS', 'SYSLIB_DEPS']
index aecacb7fd15f2355ac59a4124ba8392f4f12c3cd..654a16878e599623fbc0cb25a60ff651d0fb72ba 100644 (file)
@@ -86,12 +86,6 @@ def vcs_dir_contents(path):
             env = dict(os.environ)
             env["GIT_DIR"] = os.path.join(repo, ".git")
             break
-        elif os.path.isdir(os.path.join(repo, ".bzr")):
-            ls_files_cmd = [ 'bzr', 'ls', '--recursive', '--versioned',
-                             os_path_relpath(path, repo)]
-            cwd = repo
-            env = None
-            break
         repo = os.path.dirname(repo)
     if repo == "/":
         raise Exception("unsupported or no vcs for %s" % path)
diff --git a/buildtools/wafsamba/samba_git.py b/buildtools/wafsamba/samba_git.py
new file mode 100644 (file)
index 0000000..c58a579
--- /dev/null
@@ -0,0 +1,57 @@
+import os
+import subprocess
+
+def find_git(env=None):
+    """Find the git binary."""
+    if env is not None and 'GIT' in env:
+        return env['GIT']
+
+    # Get version from GIT
+    if os.path.exists("/usr/bin/git"):
+        # this is useful when doing make dist without configuring
+        return "/usr/bin/git"
+
+    return None
+
+
+def has_submodules(path):
+    """Check whether a source directory is git-versioned and has submodules.
+
+    :param path: Path to Samba source directory
+    """
+    return (os.path.isdir(os.path.join(path, ".git")) and
+            os.path.isfile(os.path.join(path, ".gitmodules")))
+
+
+def read_submodule_status(path, env=None):
+    """Check status of submodules.
+
+    :param path: Path to git directory
+    :param env: Optional waf environment
+    :return: Yields tuples with submodule relpath and status
+        (one of: 'out-of-date', 'not-checked-out', 'up-to-date')
+    :raise RuntimeError: raised when parsing of 'git submodule status' output
+        fails.
+    """
+    if not has_submodules(path):
+        # No point in running git.
+        return
+    git = find_git(env)
+    if git is None:
+        return
+    p = subprocess.Popen([git, "submodule", "status"], stdout=subprocess.PIPE,
+        cwd=path)
+    (stdout, stderr) = p.communicate(None)
+    for l in stdout.splitlines():
+        l = l.rstrip()
+        status = l[0]
+        l = l[1:]
+        parts = l.split(" ")
+        if len(parts) > 2 and status in ("-", "+"):
+            yield (parts[1], "out-of-date")
+        elif len(parts) == 2 and status == "-":
+            yield (parts[1], "not-checked-out")
+        elif len(parts) > 2 and status == " ":
+            yield (parts[1], "up-to-date")
+        else:
+            raise RuntimeError("Unable to parse submodule status: %r, %r" % (status, parts))
index aa7f14331a37aa64db31d1ba70192e88441f75b9..3d0c23a521cd50642744718d4c832cfc18724726 100644 (file)
@@ -59,90 +59,97 @@ def install_library(self):
 
     bld = self.bld
 
-    install_ldflags = install_rpath(self)
-    build_ldflags   = build_rpath(bld)
-
-    if not Options.is_install or not getattr(self, 'samba_install', True):
-        # just need to set the build rpath if we are not installing
-        self.env.RPATH = build_ldflags
-        return
-
-    # setup the install path, expanding variables
-    install_path = getattr(self, 'samba_inst_path', None)
-    if install_path is None:
-        if getattr(self, 'private_library', False):
-            install_path = '${PRIVATELIBDIR}'
-        else:
-            install_path = '${LIBDIR}'
-    install_path = bld.EXPAND_VARIABLES(install_path)
-
-    target_name = self.target
-
-    if install_ldflags != build_ldflags:
-        # we will be creating a new target name, and using that for the
-        # install link. That stops us from overwriting the existing build
-        # target, which has different ldflags
-        self.done_install_library = True
-        t = self.clone('default')
-        t.posted = False
-        t.target += '.inst'
-        self.env.RPATH = build_ldflags
-    else:
-        t = self
-
-    t.env.RPATH = install_ldflags
+    default_env = bld.all_envs['default']
+    try:
+        if self.env['IS_EXTRA_PYTHON']:
+            bld.all_envs['default'] = bld.all_envs['extrapython']
 
-    dev_link     = None
+        install_ldflags = install_rpath(self)
+        build_ldflags   = build_rpath(bld)
 
-    # in the following the names are:
-    # - inst_name is the name with .inst. in it, in the build
-    #   directory
-    # - install_name is the name in the install directory
-    # - install_link is a symlink in the install directory, to install_name
+        if not Options.is_install or not getattr(self, 'samba_install', True):
+            # just need to set the build rpath if we are not installing
+            self.env.RPATH = build_ldflags
+            return
 
-    if getattr(self, 'samba_realname', None):
-        install_name = self.samba_realname
-        install_link = None
-        if getattr(self, 'soname', ''):
-            install_link = self.soname
-        if getattr(self, 'samba_type', None) == 'PYTHON':
-            inst_name    = bld.make_libname(t.target, nolibprefix=True, python=True)
+        # setup the install path, expanding variables
+        install_path = getattr(self, 'samba_inst_path', None)
+        if install_path is None:
+            if getattr(self, 'private_library', False):
+                install_path = '${PRIVATELIBDIR}'
+            else:
+                install_path = '${LIBDIR}'
+        install_path = bld.EXPAND_VARIABLES(install_path)
+
+        target_name = self.target
+
+        if install_ldflags != build_ldflags:
+            # we will be creating a new target name, and using that for the
+            # install link. That stops us from overwriting the existing build
+            # target, which has different ldflags
+            self.done_install_library = True
+            t = self.clone(self.env)
+            t.posted = False
+            t.target += '.inst'
+            self.env.RPATH = build_ldflags
         else:
+            t = self
+
+        t.env.RPATH = install_ldflags
+
+        dev_link     = None
+
+        # in the following the names are:
+        # - inst_name is the name with .inst. in it, in the build
+        #   directory
+        # - install_name is the name in the install directory
+        # - install_link is a symlink in the install directory, to install_name
+
+        if getattr(self, 'samba_realname', None):
+            install_name = self.samba_realname
+            install_link = None
+            if getattr(self, 'soname', ''):
+                install_link = self.soname
+            if getattr(self, 'samba_type', None) == 'PYTHON':
+                inst_name    = bld.make_libname(t.target, nolibprefix=True, python=True)
+            else:
+                inst_name    = bld.make_libname(t.target)
+        elif self.vnum:
+            vnum_base    = self.vnum.split('.')[0]
+            install_name = bld.make_libname(target_name, version=self.vnum)
+            install_link = bld.make_libname(target_name, version=vnum_base)
+            inst_name    = bld.make_libname(t.target)
+            if not self.private_library:
+                # only generate the dev link for non-bundled libs
+                dev_link     = bld.make_libname(target_name)
+        elif getattr(self, 'soname', ''):
+            install_name = bld.make_libname(target_name)
+            install_link = self.soname
             inst_name    = bld.make_libname(t.target)
-    elif self.vnum:
-        vnum_base    = self.vnum.split('.')[0]
-        install_name = bld.make_libname(target_name, version=self.vnum)
-        install_link = bld.make_libname(target_name, version=vnum_base)
-        inst_name    = bld.make_libname(t.target)
-        if not self.private_library:
-            # only generate the dev link for non-bundled libs
-            dev_link     = bld.make_libname(target_name)
-    elif getattr(self, 'soname', ''):
-        install_name = bld.make_libname(target_name)
-        install_link = self.soname
-        inst_name    = bld.make_libname(t.target)
-    else:
-        install_name = bld.make_libname(target_name)
-        install_link = None
-        inst_name    = bld.make_libname(t.target)
-
-    if t.env.SONAME_ST:
-        # ensure we get the right names in the library
-        if install_link:
-            t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link)
         else:
-            t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name)
-        t.env.SONAME_ST = ''
+            install_name = bld.make_libname(target_name)
+            install_link = None
+            inst_name    = bld.make_libname(t.target)
 
-    # tell waf to install the library
-    bld.install_as(os.path.join(install_path, install_name),
-                   os.path.join(self.path.abspath(bld.env), inst_name),
-                   chmod=MODE_755)
-    if install_link and install_link != install_name:
-        # and the symlink if needed
-        bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name))
-    if dev_link:
-        bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name))
+        if t.env.SONAME_ST:
+            # ensure we get the right names in the library
+            if install_link:
+                t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link)
+            else:
+                t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name)
+            t.env.SONAME_ST = ''
+
+        # tell waf to install the library
+        bld.install_as(os.path.join(install_path, install_name),
+                       os.path.join(self.path.abspath(bld.env), inst_name),
+                       chmod=MODE_755)
+        if install_link and install_link != install_name:
+            # and the symlink if needed
+            bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name))
+        if dev_link:
+            bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name))
+    finally:
+        bld.all_envs['default'] = default_env
 
 
 @feature('cshlib')
index 5def5803804ce9e4b809c7af406abe490b0820a3..51d514ec75a18463f2c427cf1da3cb955909f19a 100644 (file)
@@ -287,45 +287,3 @@ def samba_before_apply_obj_vars(self):
     for i in v['LIBPATH']:
         if is_standard_libpath(v, i):
             v['LIBPATH'].remove(i)
-
-@feature('cc')
-@before('apply_incpaths', 'apply_obj_vars_cc')
-def samba_stash_cppflags(self):
-    """Fix broken waf ordering of CPPFLAGS"""
-
-    self.env.SAVED_CPPFLAGS = self.env.CPPFLAGS
-    self.env.CPPFLAGS = []
-
-@feature('cc')
-@after('apply_incpaths', 'apply_obj_vars_cc')
-def samba_pop_cppflags(self):
-    """append stashed user CPPFLAGS after our internally computed flags"""
-
-    #
-    # Note that we don't restore the values to 'CPPFLAGS',
-    # but to _CCINCFLAGS instead.
-    #
-    # buildtools/wafadmin/Tools/cc.py defines the 'cc' task generator as
-    # '${CC} ${CCFLAGS} ${CPPFLAGS} ${_CCINCFLAGS} ${_CCDEFFLAGS} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}'
-    #
-    # Our goal is to effectively invert the order of ${CPPFLAGS} and
-    # ${_CCINCFLAGS}.
-    self.env.append_value('_CCINCFLAGS', self.env.SAVED_CPPFLAGS)
-    self.env.SAVED_CPPFLAGS = []
-
-@feature('cprogram', 'cshlib', 'cstaticlib')
-@before('apply_obj_vars', 'add_extra_flags')
-def samba_stash_linkflags(self):
-    """stash away LINKFLAGS in order to fix waf's broken ordering wrt or
-    user LDFLAGS"""
-
-    self.env.SAVE_LINKFLAGS = self.env.LINKFLAGS
-    self.env.LINKFLAGS = []
-
-@feature('cprogram', 'cshlib', 'cstaticlib')
-@after('apply_obj_vars', 'add_extra_flags')
-def samba_pop_linkflags(self):
-    """after apply_obj_vars append saved LDFLAGS"""
-
-    self.env.append_value('LINKFLAGS', self.env.SAVE_LINKFLAGS)
-    self.env.SAVE_LINKFLAGS = []
index b4427d3688471c28230aff36173c4aabd70cf4bf..04699927624f8ee2745783b1026e4f19a42c40a2 100644 (file)
@@ -140,9 +140,9 @@ def write_build_options_footer(fp):
     fp.write("       output(screen, \"   sizeof(int):          %lu\\n\",(unsigned long)sizeof(int));\n")
     fp.write("       output(screen, \"   sizeof(long):         %lu\\n\",(unsigned long)sizeof(long));\n")
     fp.write("       output(screen, \"   sizeof(long long):    %lu\\n\",(unsigned long)sizeof(long long));\n")
-    fp.write("       output(screen, \"   sizeof(uint8):        %lu\\n\",(unsigned long)sizeof(uint8));\n")
-    fp.write("       output(screen, \"   sizeof(uint16):       %lu\\n\",(unsigned long)sizeof(uint16));\n")
-    fp.write("       output(screen, \"   sizeof(uint32):       %lu\\n\",(unsigned long)sizeof(uint32));\n")
+    fp.write("       output(screen, \"   sizeof(uint8_t):      %lu\\n\",(unsigned long)sizeof(uint8_t));\n")
+    fp.write("       output(screen, \"   sizeof(uint16_t):     %lu\\n\",(unsigned long)sizeof(uint16_t));\n")
+    fp.write("       output(screen, \"   sizeof(uint32_t):     %lu\\n\",(unsigned long)sizeof(uint32_t));\n")
     fp.write("       output(screen, \"   sizeof(short):        %lu\\n\",(unsigned long)sizeof(short));\n")
     fp.write("       output(screen, \"   sizeof(void*):        %lu\\n\",(unsigned long)sizeof(void*));\n")
     fp.write("       output(screen, \"   sizeof(size_t):       %lu\\n\",(unsigned long)sizeof(size_t));\n")
index 2393c72c6925a077f47ea2c363a0a767bc0637db..110b15e98fe7f9393800047381531e0b0220bf0e 100644 (file)
@@ -78,7 +78,7 @@ def SAMBA_PIDL(bld, pname, source,
     t = bld(rule='cd .. && %s %s ${PERL} "${PIDL}" --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${SRC[0].abspath(env)}"' % (cpp, cc),
             ext_out    = '.c',
             before     = 'cc',
-            on_results = True,
+            update_outputs = True,
             shell      = True,
             source     = source,
             target     = out_files,
@@ -135,7 +135,7 @@ def SAMBA_PIDL_TABLES(bld, name, target):
             rule     = '${PERL} ${SRC} --output ${TGT} | sed "s|default/||" > ${TGT}',
             ext_out  = '.c',
             before   = 'cc',
-            on_results = True,
+            update_outputs = True,
             shell    = True,
             source   = '../../librpc/tables.pl',
             target   = target,
index 1ec2f7b7fccc5612e16faed5df0c978c9673a2bf..a8f780f9f5d3f5f048de1f36826f2a196d912e73 100644 (file)
@@ -9,20 +9,70 @@ from Configure import conf
 @conf
 def SAMBA_CHECK_PYTHON(conf, mandatory=True, version=(2,4,2)):
     # enable tool to build python extensions
+    if conf.env.HAVE_PYTHON_H:
+        conf.check_python_version(version)
+        return
+
+    interpreters = []
+
+    if conf.env['EXTRA_PYTHON']:
+        conf.all_envs['extrapython'] = conf.env.copy()
+        conf.setenv('extrapython')
+        conf.env['PYTHON'] = conf.env['EXTRA_PYTHON']
+        conf.env['IS_EXTRA_PYTHON'] = 'yes'
+        conf.find_program('python', var='PYTHON', mandatory=True)
+        conf.check_tool('python')
+        try:
+            conf.check_python_version((3, 3, 0))
+        except Exception:
+            Logs.warn('extra-python needs to be Python 3.3 or later')
+            raise
+        interpreters.append(conf.env['PYTHON'])
+        conf.setenv('default')
+
     conf.find_program('python', var='PYTHON', mandatory=mandatory)
     conf.check_tool('python')
     path_python = conf.find_program('python')
     conf.env.PYTHON_SPECIFIED = (conf.env.PYTHON != path_python)
     conf.check_python_version(version)
 
+    interpreters.append(conf.env['PYTHON'])
+    conf.env.python_interpreters = interpreters
+
+
 @conf
 def SAMBA_CHECK_PYTHON_HEADERS(conf, mandatory=True):
     if conf.env["python_headers_checked"] == []:
-        conf.check_python_headers(mandatory)
+        if conf.env['EXTRA_PYTHON']:
+            conf.setenv('extrapython')
+            _check_python_headers(conf, mandatory=True)
+            conf.setenv('default')
+
+        _check_python_headers(conf, mandatory)
         conf.env["python_headers_checked"] = "yes"
+
+        if conf.env['EXTRA_PYTHON']:
+            extraversion = conf.all_envs['extrapython']['PYTHON_VERSION']
+            if extraversion == conf.env['PYTHON_VERSION']:
+                raise Utils.WafError("extrapython %s is same as main python %s" % (
+                    extraversion, conf.env['PYTHON_VERSION']))
     else:
         conf.msg("python headers", "using cache")
 
+    # we don't want PYTHONDIR in config.h, as otherwise changing
+    # --prefix causes a complete rebuild
+    del(conf.env.defines['PYTHONDIR'])
+    del(conf.env.defines['PYTHONARCHDIR'])
+
+def _check_python_headers(conf, mandatory):
+    conf.check_python_headers(mandatory=mandatory)
+
+    if conf.env['PYTHON_VERSION'] > '3':
+        abi_pattern = os.path.splitext(conf.env['pyext_PATTERN'])[0]
+        conf.env['PYTHON_SO_ABI_FLAG'] = abi_pattern % ''
+    else:
+        conf.env['PYTHON_SO_ABI_FLAG'] = ''
+
 
 def SAMBA_PYTHON(bld, name,
                  source='',
@@ -34,9 +84,13 @@ def SAMBA_PYTHON(bld, name,
                  init_function_sentinel=None,
                  local_include=True,
                  vars=None,
+                 install=True,
                  enabled=True):
     '''build a python extension for Samba'''
 
+    if bld.env['IS_EXTRA_PYTHON']:
+        name = 'extra-' + name
+
     # when we support static python modules we'll need to gather
     # the list from all the SAMBA_PYTHON() targets
     if init_function_sentinel is not None:
@@ -63,7 +117,35 @@ def SAMBA_PYTHON(bld, name,
                       target_type='PYTHON',
                       install_path='${PYTHONARCHDIR}',
                       allow_undefined_symbols=True,
-                      allow_warnings=True,
+                      install=install,
                       enabled=enabled)
 
 Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON
+
+
+def pyembed_libname(bld, name, extrapython=False):
+    return name + bld.env['PYTHON_SO_ABI_FLAG']
+
+Build.BuildContext.pyembed_libname = pyembed_libname
+
+
+def gen_python_environments(bld, extra_env_vars=()):
+    """Generate all Python environments
+
+    To be used in a for loop. Normally, the loop body will be executed once.
+
+    When --extra-python is used, the body will additionaly be executed
+    with the extra-python environment active.
+    """
+    yield
+
+    if bld.env['EXTRA_PYTHON']:
+        copied = ('GLOBAL_DEPENDENCIES', 'TARGET_TYPE') + tuple(extra_env_vars)
+        for name in copied:
+            bld.all_envs['extrapython'][name] = bld.all_envs['default'][name]
+        default_env = bld.all_envs['default']
+        bld.all_envs['default'] = bld.all_envs['extrapython']
+        yield
+        bld.all_envs['default'] = default_env
+
+Build.BuildContext.gen_python_environments = gen_python_environments
index df4a552dbeed5b3408444db9b49b7d73389ac61b..540fe447942bbb2598b4a8e9da18b5cfd21a1581 100644 (file)
@@ -386,6 +386,22 @@ def RUN_COMMAND(cmd,
     return -1
 
 
+def RUN_PYTHON_TESTS(testfiles, pythonpath=None):
+    env = LOAD_ENVIRONMENT()
+    if pythonpath is None:
+        pythonpath = os.path.join(Utils.g_module.blddir, 'python')
+    result = 0
+    for interp in env.python_interpreters:
+        for testfile in testfiles:
+            cmd = "PYTHONPATH=%s %s %s" % (pythonpath, interp, testfile)
+            print('Running Python test with %s: %s' % (interp, testfile))
+            ret = RUN_COMMAND(cmd)
+            if ret:
+                print('Python test failed: %s' % cmd)
+                result = ret
+    return result
+
+
 # make sure we have md5. some systems don't have it
 try:
     from hashlib import md5
@@ -577,7 +593,7 @@ def map_shlib_extension(ctx, name, python=False):
         return name
     (root1, ext1) = os.path.splitext(name)
     if python:
-        (root2, ext2) = os.path.splitext(ctx.env.pyext_PATTERN)
+        return ctx.env.pyext_PATTERN % root1
     else:
         (root2, ext2) = os.path.splitext(ctx.env.shlib_PATTERN)
     return root1+ext2
index 67ff23240488e9636e419782d22dffd945f9ab89..bb0be96f86942e6900b43a90c62e562881b87791 100644 (file)
@@ -1,68 +1,16 @@
 import os
 import Utils
 import samba_utils
-import sys
-
-def bzr_version_summary(path):
-    try:
-        import bzrlib
-    except ImportError:
-        return ("BZR-UNKNOWN", {})
-
-    import bzrlib.ui
-    bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
-        sys.stdin, sys.stdout, sys.stderr)
-    from bzrlib import branch, osutils, workingtree
-    from bzrlib.plugin import load_plugins
-    load_plugins()
-
-    b = branch.Branch.open(path)
-    (revno, revid) = b.last_revision_info()
-    rev = b.repository.get_revision(revid)
-
-    fields = {
-        "BZR_REVISION_ID": revid,
-        "BZR_REVNO": revno,
-        "COMMIT_DATE": osutils.format_date_with_offset_in_original_timezone(rev.timestamp,
-            rev.timezone or 0),
-        "COMMIT_TIME": int(rev.timestamp),
-        "BZR_BRANCH": rev.properties.get("branch-nick", ""),
-        }
-
-    # If possible, retrieve the git sha
-    try:
-        from bzrlib.plugins.git.object_store import get_object_store
-    except ImportError:
-        # No git plugin
-        ret = "BZR-%d" % revno
-    else:
-        store = get_object_store(b.repository)
-        store.lock_read()
-        try:
-            full_rev = store._lookup_revision_sha1(revid)
-        finally:
-            store.unlock()
-        fields["GIT_COMMIT_ABBREV"] = full_rev[:7]
-        fields["GIT_COMMIT_FULLREV"] = full_rev
-        ret = "GIT-" + fields["GIT_COMMIT_ABBREV"]
-
-    if workingtree.WorkingTree.open(path).has_changes():
-        fields["COMMIT_IS_CLEAN"] = 0
-        ret += "+"
-    else:
-        fields["COMMIT_IS_CLEAN"] = 1
-    return (ret, fields)
-
+from samba_git import find_git
 
 def git_version_summary(path, env=None):
-    # Get version from GIT
-    if not 'GIT' in env and os.path.exists("/usr/bin/git"):
-        # this is useful when doing make dist without configuring
-        env.GIT = "/usr/bin/git"
+    git = find_git(env)
 
-    if not 'GIT' in env:
+    if git is None:
         return ("GIT-UNKNOWN", {})
 
+    env.GIT = git
+
     environ = dict(os.environ)
     environ["GIT_DIR"] = '%s/.git' % path
     environ["GIT_WORK_TREE"] = path
@@ -200,8 +148,6 @@ also accepted as dictionary entries here
                 self.vcs_fields = {}
             elif os.path.exists(os.path.join(path, ".git")):
                 suffix, self.vcs_fields = git_version_summary(path, env=env)
-            elif os.path.exists(os.path.join(path, ".bzr")):
-                suffix, self.vcs_fields = bzr_version_summary(path)
             elif os.path.exists(os.path.join(path, ".distversion")):
                 suffix, self.vcs_fields = distversion_version_summary(path)
             else:
index c05431568ab41fa23b2f1a2fea8f83f2ebec63b4..c27241eff8d9c6b41770b87f7ae122f09be1317b 100644 (file)
@@ -143,6 +143,9 @@ def SAMBA_LIBRARY(bld, libname, source,
                   enabled=True):
     '''define a Samba library'''
 
+    if pyembed and bld.env['IS_EXTRA_PYTHON']:
+        public_headers = pc_files = None
+
     if LIB_MUST_BE_PRIVATE(bld, libname):
         private_library=True
 
@@ -217,10 +220,10 @@ def SAMBA_LIBRARY(bld, libname, source,
         if vnum is None and soname is None:
             raise Utils.WafError("public library '%s' must have a vnum" %
                     libname)
-        if pc_files is None:
+        if pc_files is None and not bld.env['IS_EXTRA_PYTHON']:
             raise Utils.WafError("public library '%s' must have pkg-config file" %
                        libname)
-        if public_headers is None:
+        if public_headers is None and not bld.env['IS_EXTRA_PYTHON']:
             raise Utils.WafError("public library '%s' must have header files" %
                        libname)
 
@@ -239,6 +242,8 @@ def SAMBA_LIBRARY(bld, libname, source,
                                     bundled_extension, private_library)
 
     ldflags = TO_LIST(ldflags)
+    if bld.env['ENABLE_RELRO'] is True:
+        ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now'))
 
     features = 'cc cshlib symlink_lib install_lib'
     if pyext:
@@ -638,7 +643,7 @@ def SAMBA_GENERATOR(bld, name, rule, source='', target='',
         source=bld.EXPAND_VARIABLES(source, vars=vars),
         target=target,
         shell=isinstance(rule, str),
-        on_results=True,
+        update_outputs=True,
         before='cc',
         ext_out='.c',
         samba_type='GENERATOR',
@@ -886,7 +891,8 @@ def SAMBAMANPAGES(bld, manpages, extra_source=None):
     '''build and install manual pages'''
     bld.env.SAMBA_EXPAND_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/expand-sambadoc.xsl'
     bld.env.SAMBA_MAN_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/man.xsl'
-    bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.srcnode.abspath() + '/bin/default/docs-xml/build/catalog.xml'
+    bld.env.SAMBA_CATALOG = bld.srcnode.abspath() + '/bin/default/docs-xml/build/catalog.xml'
+    bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.env.SAMBA_CATALOG
 
     for m in manpages.split():
         source = m + '.xml'
@@ -896,6 +902,7 @@ def SAMBAMANPAGES(bld, manpages, extra_source=None):
                             source=source,
                             target=m,
                             group='final',
+                            dep_vars=['SAMBA_MAN_XSL', 'SAMBA_EXPAND_XSL', 'SAMBA_CATALOG'],
                             rule='''XML_CATALOG_FILES="${SAMBA_CATALOGS}"
                                     export XML_CATALOG_FILES
                                     ${XSLTPROC} --xinclude --stringparam noreference 0 -o ${TGT}.xml --nonet ${SAMBA_EXPAND_XSL} ${SRC[0].abspath(env)}
index 8027c00dd213eea76f3a6660e14770ba204620bf..d6bb6885a1cc0fb7c05b874f89408144f988d4de 100755 (executable)
@@ -41,10 +41,10 @@ def set_options(opt):
                    help=("comma separated list of libraries to not apply extension to [%s]" % extension_exception),
                    action="store", dest='PRIVATE_EXTENSION_EXCEPTION', default=extension_exception)
 
-    builtin_defauilt = Options.options['BUILTIN_LIBRARIES_DEFAULT']
+    builtin_default = Options.options['BUILTIN_LIBRARIES_DEFAULT']
     gr.add_option('--builtin-libraries',
-                   help=("command separated list of libraries to build directly into binaries [%s]" % builtin_defauilt),
-                   action="store", dest='BUILTIN_LIBRARIES', default=builtin_defauilt)
+                   help=("command separated list of libraries to build directly into binaries [%s]" % builtin_default),
+                   action="store", dest='BUILTIN_LIBRARIES', default=builtin_default)
 
     gr.add_option('--minimum-library-version',
                    help=("list of minimum system library versions (LIBNAME1:version,LIBNAME2:version)"),
@@ -195,6 +195,12 @@ def set_options(opt):
                    help='tag release in git at the same time',
                    type='string', action='store', dest='TAG_RELEASE')
 
+    opt.add_option('--extra-python', type=str,
+                    help=("build selected libraries for the specified "
+                          "additional version of Python "
+                          "(example: --extra-python=/usr/bin/python3)"),
+                    metavar="PYTHON", dest='EXTRA_PYTHON', default=None)
+
 
 @wafsamba.runonce
 def configure(conf):
@@ -266,6 +272,8 @@ def configure(conf):
     conf.env.AUTOCONF_HOST  = Options.options.AUTOCONF_HOST
     conf.env.AUTOCONF_PROGRAM_PREFIX = Options.options.AUTOCONF_PROGRAM_PREFIX
 
+    conf.env.EXTRA_PYTHON = Options.options.EXTRA_PYTHON
+
     if (conf.env.AUTOCONF_HOST and
         conf.env.AUTOCONF_BUILD and
         conf.env.AUTOCONF_BUILD != conf.env.AUTOCONF_HOST):
@@ -383,7 +391,7 @@ def configure(conf):
     conf.CHECK_INLINE()
 
     # check for pkgconfig
-    conf.check_cfg(atleast_pkgconfig_version='0.0.0')
+    conf.CHECK_CFG(atleast_pkgconfig_version='0.0.0')
 
     conf.DEFINE('_GNU_SOURCE', 1, add_to_cflags=True)
     conf.DEFINE('_XOPEN_SOURCE_EXTENDED', 1, add_to_cflags=True)
index 3b56898a08759adddbf194d40145eb43064129cb..ece6ccb8f0c9a67d878b8c9f2ee24fd2d8f3b581 100644 (file)
  *   - when using talloc_enable_leak_report(), giving directly NULL as a parent
  *     context implicitly refers to a hidden "null context" global variable, so
  *     this should not be used in a multi-threaded environment without proper
- *     synchronization.
+ *     synchronization. In threaded code turn off null tracking using
+ *     talloc_disable_null_tracking().
  *   - the context returned by talloc_autofree_context() is also global so
  *     shouldn't be used by several threads simultaneously without
  *     synchronization.
index 02777b9f774e85b6f14646103d585b9a74808dda..418c38b5a188c5bbf9d21ae2b2512836753c658a 100644 (file)
@@ -40,4 +40,6 @@ recursively frees all of its descendants as well.
 
 @subpage libtalloc_bestpractices
 
-*/
\ No newline at end of file
+@subpage libtalloc_threads
+
+*/
diff --git a/doc/tutorial_threads.dox b/doc/tutorial_threads.dox
new file mode 100644 (file)
index 0000000..111bbf5
--- /dev/null
@@ -0,0 +1,203 @@
+/**
+@page libtalloc_threads Chapter 8: Using threads with talloc
+
+@section Talloc and thread safety
+
+The talloc library is not internally thread-safe, in that accesses
+to variables on a talloc context are not controlled by mutexes or
+other thread-safe primitives.
+
+However, so long as talloc_disable_null_tracking() is called from
+the main thread to disable global variable access within talloc,
+then each thread can safely use its own top level talloc context
+allocated off the NULL context.
+
+For example:
+
+@code
+static void *thread_fn(void *arg)
+{
+       const char *ctx_name = (const char *)arg;
+        /*
+         * Create a new top level talloc hierarchy in
+         * this thread.
+         */
+       void *top_ctx = talloc_named_const(NULL, 0, "top");
+       if (top_ctx == NULL) {
+               return NULL;
+       }
+       sub_ctx = talloc_named_const(top_ctx, 100, ctx_name);
+       if (sub_ctx == NULL) {
+               return NULL;
+       }
+
+       /*
+        * Do more processing/talloc calls on top_ctx
+        * and its children.
+        */
+       ......
+
+       talloc_free(top_ctx);
+       return value;
+}
+@endcode
+
+is a perfectly safe use of talloc within a thread.
+
+The problem comes when one thread wishes to move some
+memory allocated on its local top level talloc context
+to another thread. Care must be taken to add data access
+exclusion to prevent memory corruption. One method would
+be to lock a mutex before any talloc call on each thread,
+but this would push the burden of total talloc thread-safety
+on the poor user of the library.
+
+A much easier way to transfer talloced memory between
+threads is by the use of an intermediate, mutex locked,
+intermediate variable.
+
+An example of this is below - taken from test code inside
+the talloc testsuite.
+
+The main thread creates 1000 sub-threads, and then accepts
+the transfer of some thread-talloc'ed memory onto its top
+level context from each thread in turn.
+
+A pthread mutex and condition variable are used to
+synchronize the transfer via the intermediate_ptr
+variable.
+
+@code
+/* Required sync variables. */
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
+
+/* Intermediate talloc pointer for transfer. */
+static void *intermediate_ptr;
+
+/* Subthread. */
+static void *thread_fn(void *arg)
+{
+       int ret;
+       const char *ctx_name = (const char *)arg;
+       void *sub_ctx = NULL;
+       /*
+        * Do stuff that creates a new talloc hierarchy in
+        * this thread.
+        */
+       void *top_ctx = talloc_named_const(NULL, 0, "top");
+       if (top_ctx == NULL) {
+               return NULL;
+       }
+       sub_ctx = talloc_named_const(top_ctx, 100, ctx_name);
+       if (sub_ctx == NULL) {
+               return NULL;
+       }
+
+       /*
+        * Now transfer a pointer from our hierarchy
+        * onto the intermediate ptr.
+        */
+       ret = pthread_mutex_lock(&mtx);
+       if (ret != 0) {
+               talloc_free(top_ctx);
+               return NULL;
+       }
+
+       /* Wait for intermediate_ptr to be free. */
+       while (intermediate_ptr != NULL) {
+               ret = pthread_cond_wait(&condvar, &mtx);
+               if (ret != 0) {
+                       talloc_free(top_ctx);
+                       return NULL;
+               }
+       }
+
+       /* and move our memory onto it from our toplevel hierarchy. */
+       intermediate_ptr = talloc_move(NULL, &sub_ctx);
+
+       /* Tell the main thread it's ready for pickup. */
+       pthread_cond_broadcast(&condvar);
+       pthread_mutex_unlock(&mtx);
+
+       talloc_free(top_ctx);
+       return NULL;
+}
+
+/* Main thread. */
+
+#define NUM_THREADS 1000
+
+static bool test_pthread_talloc_passing(void)
+{
+       int i;
+       int ret;
+       char str_array[NUM_THREADS][20];
+       pthread_t thread_id;
+       void *mem_ctx;
+
+       /*
+        * Important ! Null tracking breaks threaded talloc.
+        * It *must* be turned off.
+        */
+       talloc_disable_null_tracking();
+
+       /* Main thread toplevel context. */
+       mem_ctx = talloc_named_const(NULL, 0, "toplevel");
+       if (mem_ctx == NULL) {
+               return false;
+       }
+
+       /*
+        * Spin off NUM_THREADS threads.
+        * They will use their own toplevel contexts.
+        */
+       for (i = 0; i < NUM_THREADS; i++) {
+               (void)snprintf(str_array[i],
+                               20,
+                               "thread:%d",
+                               i);
+               if (str_array[i] == NULL) {
+                       return false;
+               }
+               ret = pthread_create(&thread_id,
+                               NULL,
+                               thread_fn,
+                               str_array[i]);
+               if (ret != 0) {
+                       return false;
+               }
+       }
+
+       /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */
+       for (i = 0; i < NUM_THREADS; i++) {
+               ret = pthread_mutex_lock(&mtx);
+               if (ret != 0) {
+                       talloc_free(mem_ctx);
+                       return false;
+               }
+
+               /* Wait for intermediate_ptr to have our data. */
+               while (intermediate_ptr == NULL) {
+                       ret = pthread_cond_wait(&condvar, &mtx);
+                       if (ret != 0) {
+                               talloc_free(mem_ctx);
+                               return false;
+                       }
+               }
+
+               /* and move it onto our toplevel hierarchy. */
+               (void)talloc_move(mem_ctx, &intermediate_ptr);
+
+               /* Tell the sub-threads we're ready for another. */
+               pthread_cond_broadcast(&condvar);
+               pthread_mutex_unlock(&mtx);
+       }
+
+       /* Dump the hierarchy. */
+       talloc_report(mem_ctx, stdout);
+       talloc_free(mem_ctx);
+       return true;
+}
+@endcode
+*/
index 2a9ca3e5abb6b27c021ce903ed5099b2b5cd1762..dccf5142838fdb3857d3af20734ca386e0e1d3ec 100644 (file)
@@ -64,14 +64,22 @@ int rep_ftruncate(int f, off_t l)
 
 
 #ifndef HAVE_STRLCPY
-/* like strncpy but does not 0 fill the buffer and always null 
-   terminates. bufsize is the size of the destination buffer */
+/*
+ * Like strncpy but does not 0 fill the buffer and always null
+ * terminates. bufsize is the size of the destination buffer.
+ * Returns the length of s.
+ */
 size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
 {
        size_t len = strlen(s);
        size_t ret = len;
-       if (bufsize <= 0) return 0;
-       if (len >= bufsize) len = bufsize-1;
+
+       if (bufsize <= 0) {
+               return 0;
+       }
+       if (len >= bufsize) {
+               len = bufsize - 1;
+       }
        memcpy(d, s, len);
        d[len] = 0;
        return ret;
@@ -510,11 +518,10 @@ long long int rep_strtoll(const char *str, char **endptr, int base)
 }
 #else
 #ifdef HAVE_BSD_STRTOLL
-#ifdef HAVE_STRTOQ
 long long int rep_strtoll(const char *str, char **endptr, int base)
 {
-       long long int nb = strtoq(str, endptr, base);
-       /* In linux EINVAL is only returned if base is not ok */
+       long long int nb = strtoll(str, endptr, base);
+       /* With glibc EINVAL is only returned if base is not ok */
        if (errno == EINVAL) {
                if (base == 0 || (base >1 && base <37)) {
                        /* Base was ok so it's because we were not
@@ -526,9 +533,6 @@ long long int rep_strtoll(const char *str, char **endptr, int base)
        }
        return nb;
 }
-#else
-#error "You need the strtoq function"
-#endif /* HAVE_STRTOQ */
 #endif /* HAVE_BSD_STRTOLL */
 #endif /* HAVE_STRTOLL */
 
index 25d3502aa6473f4fb1fd786c39b622b29fa7953d..fe6d0fbac541c968011ed128804956e090b89bcc 100644 (file)
 
 #if defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) && \
        !defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST)
-
 #define pthread_mutexattr_setrobust pthread_mutexattr_setrobust_np
+#endif
 
-/*
- * We assume that PTHREAD_MUTEX_ROBUST_NP goes along with
- * pthread_mutexattr_setrobust_np()
- */
+#if defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP) && \
+       !defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST)
 #define PTHREAD_MUTEX_ROBUST PTHREAD_MUTEX_ROBUST_NP
-
 #endif
 
 #if defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP) && \
index 9e2115bb8115317ad1be4619640c64daa98b2f17..0816f611516d654875c791c6ff5b4329df7a10c6 100644 (file)
@@ -70,7 +70,8 @@ static int os2_delete(DIR *d)
             de && i < READDIR_SIZE; 
             de=readdir(d), i++) {
                offsets[i] = telldir(d);
-               strcpy(names[i], de->d_name);
+               /* strlcpy not available here */
+               snprintf(names[i], sizeof(names[i]), "%s", de->d_name);
        }
 
        if (i == 0) {
index 52629ec82e5b3f271e47ab0fd4ab03e5c2dbf62a..961b77d9eaf81f9e3184464b1ddc3254873f987e 100644 (file)
@@ -69,19 +69,23 @@ static int test_ftruncate(void)
        }
        if (ftruncate(fd, size) != 0) {
                printf("failure: ftruncate [\n%s\n]\n", strerror(errno));
+               close(fd);
                return false;
        }
        if (fstat(fd, &st) != 0) {
                printf("failure: ftruncate [\nfstat failed - %s\n]\n", strerror(errno));
+               close(fd);
                return false;
        }
        if (st.st_size != size) {
                printf("failure: ftruncate [\ngave wrong size %d - expected %d\n]\n",
                       (int)st.st_size, size);
+               close(fd);
                return false;
        }
        unlink(TESTFILE);
        printf("success: ftruncate\n");
+       close(fd);
        return true;
 }
 
@@ -272,6 +276,7 @@ static int test_strndup(void)
        x = strndup("bla", 10);
        if (strcmp(x, "bla") != 0) {
                printf("failure: strndup [\ninvalid\n]\n");
+               free(x);
                return false;
        }
        free(x);
@@ -887,6 +892,7 @@ static int test_utime(void)
                printf("failure: utime [\n"
                       "fstat (1) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -896,6 +902,7 @@ static int test_utime(void)
                printf("failure: utime [\n"
                       "utime(&u) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -903,6 +910,7 @@ static int test_utime(void)
                printf("failure: utime [\n"
                       "fstat (2) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -910,6 +918,7 @@ static int test_utime(void)
                printf("failure: utime [\n"
                       "utime(NULL) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -917,6 +926,7 @@ static int test_utime(void)
                printf("failure: utime [\n"
                       "fstat (3) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -926,6 +936,7 @@ static int test_utime(void)
                       "%s: %s(%d) %s %s(%d)\n]\n", \
                       __location__, \
                       #a, (int)a, #c, #b, (int)b); \
+               close(fd); \
                return false; \
        } \
 } while(0)
@@ -945,6 +956,7 @@ static int test_utime(void)
 
        unlink(TESTFILE);
        printf("success: utime\n");
+       close(fd);
        return true;
 }
 
@@ -969,6 +981,7 @@ static int test_utimes(void)
                printf("failure: utimes [\n"
                       "fstat (1) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -979,6 +992,7 @@ static int test_utimes(void)
                printf("failure: utimes [\n"
                       "utimes(tv) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -986,6 +1000,7 @@ static int test_utimes(void)
                printf("failure: utimes [\n"
                       "fstat (2) failed - %s\n]\n",
                       strerror(errno));
+               close(fd);
                return false;
        }
 
@@ -995,6 +1010,7 @@ static int test_utimes(void)
                       "%s: %s(%d) != %s(%d)\n]\n", \
                       __location__, \
                       #a, (int)a, #b, (int)b); \
+               close(fd); \
                return false; \
        } \
 } while(0)
@@ -1006,6 +1022,7 @@ static int test_utimes(void)
 
        unlink(TESTFILE);
        printf("success: utimes\n");
+       close(fd);
        return true;
 }
 
index f8a017920df515b82dd1abad9ed989f6042acf6e..516db2ff6e0f105a956de5e0901cef0fa12007ff 100644 (file)
@@ -16,7 +16,7 @@ sys.path.insert(0, srcdir + '/buildtools/wafsamba')
 import wafsamba, samba_dist
 import Options
 
-samba_dist.DIST_DIRS('lib/replace buildtools:buildtools')
+samba_dist.DIST_DIRS('lib/replace buildtools:buildtools third_party/waf:third_party/waf')
 
 def set_options(opt):
     opt.BUILTIN_DEFAULT('NONE')
@@ -53,7 +53,7 @@ def configure(conf):
     conf.CHECK_HEADERS('sys/uio.h ifaddrs.h direct.h dirent.h')
     conf.CHECK_HEADERS('windows.h winsock2.h ws2tcpip.h')
     conf.CHECK_HEADERS('errno.h')
-    conf.CHECK_HEADERS('gcrypt.h getopt.h iconv.h')
+    conf.CHECK_HEADERS('getopt.h iconv.h')
     conf.CHECK_HEADERS('memory.h nss.h sasl/sasl.h')
 
     conf.CHECK_FUNCS_IN('inotify_init', 'inotify', checklibc=True,
@@ -74,6 +74,7 @@ def configure(conf):
     conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h malloc.h')
     conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h')
     conf.CHECK_HEADERS('sys/atomic.h')
+    conf.CHECK_HEADERS('libgen.h')
 
     # Check for process set name support
     conf.CHECK_CODE('''
@@ -135,6 +136,7 @@ def configure(conf):
     conf.CHECK_TYPE_IN('sa_family_t', 'sys/socket.h')
 
     conf.CHECK_TYPE_IN('sig_atomic_t', 'signal.h', define='HAVE_SIG_ATOMIC_T_TYPE')
+    conf.CHECK_FUNCS('sigsetmask siggetmask sigprocmask sigblock sigaction sigset')
 
     conf.CHECK_FUNCS_IN('''inet_ntoa inet_aton inet_ntop inet_pton connect gethostbyname
                            getaddrinfo getnameinfo freeaddrinfo gai_strerror socketpair''',
@@ -243,7 +245,7 @@ def configure(conf):
     conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf')
     conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull')
     conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq memalign posix_memalign')
-    conf.CHECK_FUNCS('prctl')
+    conf.CHECK_FUNCS('prctl dirname basename')
 
     # libbsd on some platforms provides strlcpy and strlcat
     if not conf.CHECK_FUNCS('strlcpy strlcat'):
@@ -446,21 +448,15 @@ removeea setea
 
     if conf.CONFIG_SET('HAVE_PTHREAD'):
 
-        conf.CHECK_DECLS('pthread_mutexattr_setrobust', headers='pthread.h')
-        if not conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEXATTR_SETROBUST'):
-            conf.CHECK_DECLS('pthread_mutexattr_setrobust_np',
-                             headers='pthread.h')
-
         conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust', 'pthread',
                             checklibc=True, headers='pthread.h')
         if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST'):
             conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust_np', 'pthread',
                                 checklibc=True, headers='pthread.h')
 
-        conf.CHECK_DECLS('pthread_mutex_consistent', headers='pthread.h')
-        if not conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_CONSISTENT'):
-            conf.CHECK_DECLS('pthread_mutex_consistent_np',
-                             headers='pthread.h')
+        conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST', headers='pthread.h')
+        if not conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST'):
+            conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST_NP', headers='pthread.h')
 
         conf.CHECK_FUNCS_IN('pthread_mutex_consistent', 'pthread',
                             checklibc=True, headers='pthread.h')
@@ -470,6 +466,8 @@ removeea setea
 
         if ((conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST') or
              conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP')) and
+            (conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST') or
+             conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP')) and
             (conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT') or
              conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT_NP'))):
             conf.DEFINE('HAVE_ROBUST_MUTEXES', 1)
index 553eaec7ea8c88f242d122734880a4f90d9ade63..6139fe738257c58d2a882f9b49ff51d6f38f6a83 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
 <refentry>
+  <refentryinfo><date>2015-04-10</date></refentryinfo>
   <refmeta>
     <refentrytitle>talloc</refentrytitle>
     <manvolnum>3</manvolnum>
           </listitem>
           <listitem>
             <para>
-             you can talloc_free() the pointer itself.  That will destroy
-             the most recently established parent to the pointer and leave
-             the pointer as a child of its current parent.
+             you can talloc_free() the pointer itself if it has at maximum one
+             parent. This behaviour has been changed since the release of version
+             2.0. Further informations in the description of "talloc_free".
             </para>
           </listitem>
         </itemizedlist>
        linkend="talloc_unlink"><quote>talloc_unlink()</quote></link>.
       </para>
     </refsect2>
-    <refsect2 id="talloc_unlink"><title>int talloc_unlink(const void *ctx, const void *ptr);</title>
+    <refsect2 id="talloc_unlink"><title>int talloc_unlink(const void *ctx, void *ptr);</title>
         <para>
          The talloc_unlink() function removes a specific parent from
          <emphasis role="italic">ptr</emphasis>. The <emphasis
index b7426bb1124d5c03af4b1351e1e1c55d039d6f82..b87c94edf20c5325d3cde598bfa914bd478ed815 100644 (file)
@@ -6,6 +6,6 @@ includedir=@includedir@
 Name: pytalloc-util
 Description: Utility functions for using talloc objects with Python
 Version: @TALLOC_VERSION@
-Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util
+Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_SO_ABI_FLAG@
 Cflags: -I${includedir}
 URL: http://talloc.samba.org/
index 80196c6c77b58c395f5dde78e3d19f6d9de4c4a3..3afae9ce012bffae82e1170544c98e9d5e97f394 100644 (file)
 #include <talloc.h>
 #include <pytalloc.h>
 
-void inittalloc(void);
+static PyTypeObject TallocObject_Type;
+
+#if PY_MAJOR_VERSION >= 3
+#define PyStr_FromFormat PyUnicode_FromFormat
+#else
+#define PyStr_FromFormat PyString_FromFormat
+#endif
 
 /* print a talloc tree report for a talloc python object */
 static PyObject *pytalloc_report_full(PyObject *self, PyObject *args)
@@ -79,8 +85,8 @@ static PyObject *pytalloc_default_repr(PyObject *obj)
        pytalloc_Object *talloc_obj = (pytalloc_Object *)obj;
        PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj);
 
-       return PyString_FromFormat("<%s talloc object at 0x%p>", 
-                                  type->tp_name, talloc_obj->ptr);
+       return PyStr_FromFormat("<%s talloc object at 0x%p>",
+                               type->tp_name, talloc_obj->ptr);
 }
 
 /**
@@ -97,15 +103,45 @@ static void pytalloc_dealloc(PyObject* self)
 /**
  * Default (but only slightly more useful than the default) implementation of cmp.
  */
+#if PY_MAJOR_VERSION >= 3
+static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op)
+{
+       void *ptr1;
+       void *ptr2;
+       if (Py_TYPE(obj1) == Py_TYPE(obj2)) {
+               /* When types match, compare pointers */
+               ptr1 = pytalloc_get_ptr(obj1);
+               ptr2 = pytalloc_get_ptr(obj2);
+       } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) {
+               /* Otherwise, compare types */
+               ptr1 = Py_TYPE(obj1);
+               ptr2 = Py_TYPE(obj2);
+       } else {
+               Py_INCREF(Py_NotImplemented);
+               return Py_NotImplemented;
+       }
+       switch (op) {
+               case Py_EQ: return PyBool_FromLong(ptr1 == ptr2);
+               case Py_NE: return PyBool_FromLong(ptr1 != ptr2);
+               case Py_LT: return PyBool_FromLong(ptr1 < ptr2);
+               case Py_GT: return PyBool_FromLong(ptr1 > ptr2);
+               case Py_LE: return PyBool_FromLong(ptr1 <= ptr2);
+               case Py_GE: return PyBool_FromLong(ptr1 >= ptr2);
+       }
+       Py_INCREF(Py_NotImplemented);
+       return Py_NotImplemented;
+}
+#else
 static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2)
 {
        pytalloc_Object *obj1 = (pytalloc_Object *)_obj1,
                                         *obj2 = (pytalloc_Object *)_obj2;
        if (obj1->ob_type != obj2->ob_type)
-               return (obj1->ob_type - obj2->ob_type);
+               return ((char *)obj1->ob_type - (char *)obj2->ob_type);
 
        return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2));
 }
+#endif
 
 static PyTypeObject TallocObject_Type = {
        .tp_name = "talloc.Object",
@@ -114,21 +150,56 @@ static PyTypeObject TallocObject_Type = {
        .tp_dealloc = (destructor)pytalloc_dealloc,
        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
        .tp_repr = pytalloc_default_repr,
+#if PY_MAJOR_VERSION >= 3
+       .tp_richcompare = pytalloc_default_richcmp,
+#else
        .tp_compare = pytalloc_default_cmp,
+#endif
 };
 
-void inittalloc(void)
+#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.")
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "talloc",
+    .m_doc = MODULE_DOC,
+    .m_size = -1,
+    .m_methods = talloc_methods,
+};
+#endif
+
+static PyObject *module_init(void);
+static PyObject *module_init(void)
 {
        PyObject *m;
 
        if (PyType_Ready(&TallocObject_Type) < 0)
-               return;
+               return NULL;
 
-       m = Py_InitModule3("talloc", talloc_methods,
-                                          "Python wrapping of talloc-maintained objects.");
+#if PY_MAJOR_VERSION >= 3
+       m = PyModule_Create(&moduledef);
+#else
+       m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC);
+#endif
        if (m == NULL)
-               return;
+               return NULL;
 
        Py_INCREF(&TallocObject_Type);
        PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type);
+       return m;
+}
+
+#if PY_MAJOR_VERSION >= 3
+PyMODINIT_FUNC PyInit_talloc(void);
+PyMODINIT_FUNC PyInit_talloc(void)
+{
+       return module_init();
+}
+#else
+void inittalloc(void);
+void inittalloc(void)
+{
+       module_init();
 }
+#endif
index 5c3876ed156a58aa23ea15193c234a5edf46277d..608328e6aca36336b38a5ce6b6a742f1a02facfd 100644 (file)
@@ -52,6 +52,8 @@ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void
 
 #define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type))
 
+#if PY_MAJOR_VERSION < 3
 PyObject *pytalloc_CObject_FromTallocPtr(void *);
+#endif
 
 #endif /* _PYTALLOC_H_ */
index 755a52bd21745cd035cb64286b2468f4659e9788..36ae5ffe053bdf83f8f2808bbc1355e139ee55e8 100644 (file)
@@ -20,6 +20,14 @@ for objects that wrap talloc-maintained memory in C. It won't write your
 bindings for you but it will make it easier to write C bindings that involve
 talloc, and take away some of the boiler plate.
 
+Python 3
+--------
+
+pytalloc can be used with Python 3. Usage from Python extension remains
+the same, but for the C utilities, the library to link to is tagged with
+Python's PEP3149 ABI tag, for example "pytalloc.cpython34m".
+To make a build for Python 3, configure with PYTHON=/usr/bin/python3.
+.
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 pytalloc_Object
 
@@ -126,6 +134,8 @@ use a generic VoidPtr Python type, which just provides an opaque object in
 Python. The caller is responsible for incrementing the talloc reference count before calling
 this function - it will dereference the talloc pointer when it is garbage collected.
 
+This function is only available on Python 2.
+
 Debug function for talloc in Python
 -----------------------------------
 
index 89a093b1cefdfcefe736c80ad967ec8a1e9e27ac..0af7c054507eab6e6a5ac8311c05d5a0f2d3ac27 100644 (file)
@@ -97,6 +97,8 @@ _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_
        return (PyObject *)ret;
 }
 
+#if PY_MAJOR_VERSION < 3
+
 static void py_cobject_talloc_free(void *ptr)
 {
        talloc_free(ptr);
@@ -110,6 +112,8 @@ _PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr)
        return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free);
 }
 
+#endif
+
 _PUBLIC_ int pytalloc_Check(PyObject *obj)
 {
        PyTypeObject *tp = pytalloc_GetObjectType();
diff --git a/talloc.i b/talloc.i
deleted file mode 100644 (file)
index a9afb97..0000000
--- a/talloc.i
+++ /dev/null
@@ -1,31 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Don't expose talloc contexts in Python code. Python does reference 
-   counting for us, so just create a new top-level talloc context.
- */
-%typemap(in, numinputs=0, noblock=1) TALLOC_CTX * {
-    $1 = NULL;
-}
-
-%define %talloctype(TYPE)
-%nodefaultctor TYPE;
-%extend TYPE {
-    ~TYPE() { talloc_free($self); }
-}
-%enddef
index 16afc9b6b8ad0ae671de48535c3653081c1e8794..aba285e72dfc1b080d891b1a68c8a33d28edff18 100644 (file)
@@ -69,7 +69,8 @@ order to be safe. In particular:
 - when using talloc_enable_leak_report(), giving directly NULL as a  
 parent context implicitly refers to a hidden "null context" global  
 variable, so this should not be used in a multi-threaded environment  
-without proper synchronization ;
+without proper synchronization. In threaded code turn off null tracking using
+talloc_disable_null_tracking(). ;
 - the context returned by talloc_autofree_context() is also global so  
 shouldn't be used by several threads simultaneously without  
 synchronization.
@@ -194,7 +195,7 @@ For more control on which parent to remove, see talloc_unlink()
 
 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-int talloc_unlink(const void *context, const void *ptr);
+int talloc_unlink(const void *context, void *ptr);
 
 The talloc_unlink() function removes a specific parent from ptr. The
 context passed must either be a context used in talloc_reference()
diff --git a/test_pytalloc.c b/test_pytalloc.c
new file mode 100644 (file)
index 0000000..f66b4e5
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+   Samba Unix SMB/CIFS implementation.
+
+   C utilities for the pytalloc test suite.
+   Provides the "_test_pytalloc" Python module.
+
+   NOTE: Please read talloc_guide.txt for full documentation
+
+   Copyright (C) Petr Viktorin 2015
+
+     ** NOTE! The following LGPL license applies to the talloc
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <Python.h>
+#include <talloc.h>
+#include <pytalloc.h>
+
+static PyObject *testpytalloc_new(PyTypeObject *mod)
+{
+       char *obj = talloc_strdup(NULL, "This is a test string");;
+       return pytalloc_steal(pytalloc_GetObjectType(), obj);
+}
+
+static PyObject *testpytalloc_get_object_type(PyObject *mod) {
+       PyObject *type = (PyObject *)pytalloc_GetObjectType();
+       Py_INCREF(type);
+       return type;
+}
+
+static PyObject *testpytalloc_reference(PyObject *mod, PyObject *args) {
+       pytalloc_Object *source = NULL;
+       void *ptr;
+
+       if (!PyArg_ParseTuple(args, "O!", pytalloc_GetObjectType(), &source))
+               return NULL;
+
+       ptr = source->ptr;
+       return pytalloc_reference_ex(pytalloc_GetObjectType(), ptr, ptr);
+}
+
+static PyMethodDef test_talloc_methods[] = {
+       { "new", (PyCFunction)testpytalloc_new, METH_NOARGS,
+               "create a talloc Object with a testing string"},
+       { "get_object_type", (PyCFunction)testpytalloc_get_object_type, METH_NOARGS,
+               "call pytalloc_GetObjectType"},
+       { "reference", (PyCFunction)testpytalloc_reference, METH_VARARGS,
+               "call pytalloc_reference_ex"},
+       { NULL }
+};
+
+static PyTypeObject DObject_Type;
+
+static int dobject_destructor(void *ptr)
+{
+       PyObject *destructor_func = *talloc_get_type(ptr, PyObject*);
+       PyObject *ret;
+       ret = PyObject_CallObject(destructor_func, NULL);
+       Py_DECREF(destructor_func);
+       if (ret == NULL) {
+               PyErr_Print();
+       } else {
+               Py_DECREF(ret);
+       }
+       return 0;
+}
+
+static PyObject *dobject_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+       PyObject *destructor_func = NULL;
+       PyObject **obj;
+
+       if (!PyArg_ParseTuple(args, "O", &destructor_func))
+               return NULL;
+       Py_INCREF(destructor_func);
+
+       obj = talloc(NULL, PyObject*);
+       *obj = destructor_func;
+
+       talloc_set_destructor((void*)obj, dobject_destructor);
+       return pytalloc_steal(&DObject_Type, obj);
+}
+
+static PyTypeObject DObject_Type = {
+       .tp_name = "_test_pytalloc.DObject",
+       .tp_basicsize = sizeof(pytalloc_Object),
+       .tp_methods = NULL,
+       .tp_new = dobject_new,
+       .tp_flags = Py_TPFLAGS_DEFAULT,
+       .tp_doc = "test talloc object that calls a function when underlying data is freed\n",
+};
+
+#define MODULE_DOC PyDoc_STR("Test utility module for pytalloc")
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "_test_pytalloc",
+    .m_doc = PyDoc_STR("Test utility module for pytalloc"),
+    .m_size = -1,
+    .m_methods = test_talloc_methods,
+};
+#endif
+
+static PyObject *module_init(void);
+static PyObject *module_init(void)
+{
+       PyObject *m;
+
+       DObject_Type.tp_base = pytalloc_GetObjectType();
+       if (PyType_Ready(&DObject_Type) < 0) {
+               return NULL;
+       }
+
+#if PY_MAJOR_VERSION >= 3
+       m = PyModule_Create(&moduledef);
+#else
+       m = Py_InitModule3("_test_pytalloc", test_talloc_methods, MODULE_DOC);
+#endif
+
+       if (m == NULL) {
+               return NULL;
+       }
+
+       Py_INCREF(&DObject_Type);
+       Py_INCREF(DObject_Type.tp_base);
+       PyModule_AddObject(m, "DObject", (PyObject *)&DObject_Type);
+
+       return m;
+}
+
+
+#if PY_MAJOR_VERSION >= 3
+PyMODINIT_FUNC PyInit__test_pytalloc(void);
+PyMODINIT_FUNC PyInit__test_pytalloc(void)
+{
+       return module_init();
+}
+#else
+void init_test_pytalloc(void);
+void init_test_pytalloc(void)
+{
+       module_init();
+}
+#endif
diff --git a/test_pytalloc.py b/test_pytalloc.py
new file mode 100644 (file)
index 0000000..a613373
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# Simple tests for the talloc python bindings.
+# Copyright (C) 2015 Petr Viktorin <pviktori@redhat.com>
+
+import unittest
+import subprocess
+import sys
+import re
+import gc
+
+import talloc
+import _test_pytalloc
+
+def dummy_func():
+    pass
+
+
+class TallocTests(unittest.TestCase):
+
+    def test_report_full(self):
+        # report_full is hardcoded to print to stdout, so use a subprocess
+        process = subprocess.Popen([
+            sys.executable, '-c',
+            """if True:
+            import talloc, _test_pytalloc
+            obj = _test_pytalloc.new()
+            talloc.report_full(obj)
+            """
+        ], stdout=subprocess.PIPE)
+        output, stderr = process.communicate()
+        output = str(output)
+        self.assertTrue("full talloc report on 'talloc.Object" in output)
+        self.assertTrue("This is a test string" in output)
+
+    def test_totalblocks(self):
+        obj = _test_pytalloc.new()
+        # Two blocks: the string, and the name
+        self.assertEqual(talloc.total_blocks(obj), 2)
+
+    def test_repr(self):
+        obj = _test_pytalloc.new()
+        prefix = '<talloc.Object talloc object at'
+        self.assertTrue(repr(obj).startswith(prefix))
+        self.assertEqual(repr(obj), str(obj))
+
+    def test_destructor(self):
+        # Check correct lifetime of the talloc'd data
+        lst = []
+        obj = _test_pytalloc.DObject(lambda: lst.append('dead'))
+        self.assertEqual(lst, [])
+        del obj
+        gc.collect()
+        self.assertEqual(lst, ['dead'])
+
+
+class TallocComparisonTests(unittest.TestCase):
+
+    def test_compare_same(self):
+        obj1 = _test_pytalloc.new()
+        self.assertTrue(obj1 == obj1)
+        self.assertFalse(obj1 != obj1)
+        self.assertTrue(obj1 <= obj1)
+        self.assertFalse(obj1 < obj1)
+        self.assertTrue(obj1 >= obj1)
+        self.assertFalse(obj1 > obj1)
+
+    def test_compare_different(self):
+        # object comparison is consistent
+        obj1, obj2 = sorted([
+            _test_pytalloc.new(),
+            _test_pytalloc.new()])
+        self.assertFalse(obj1 == obj2)
+        self.assertTrue(obj1 != obj2)
+        self.assertTrue(obj1 <= obj2)
+        self.assertTrue(obj1 < obj2)
+        self.assertFalse(obj1 >= obj2)
+        self.assertFalse(obj1 > obj2)
+
+    def test_compare_different_types(self):
+        # object comparison falls back to comparing types
+        if sys.version_info >= (3, 0):
+            # In Python 3, types are unorderable -- nothing to test
+            return
+        if talloc.Object < _test_pytalloc.DObject:
+            obj1 = _test_pytalloc.new()
+            obj2 = _test_pytalloc.DObject(dummy_func)
+        else:
+            obj2 = _test_pytalloc.new()
+            obj1 = _test_pytalloc.DObject(dummy_func)
+        self.assertFalse(obj1 == obj2)
+        self.assertTrue(obj1 != obj2)
+        self.assertTrue(obj1 <= obj2)
+        self.assertTrue(obj1 < obj2)
+        self.assertFalse(obj1 >= obj2)
+        self.assertFalse(obj1 > obj2)
+
+
+class TallocUtilTests(unittest.TestCase):
+
+    def test_get_type(self):
+        self.assertTrue(talloc.Object is _test_pytalloc.get_object_type())
+
+    def test_refrence(self):
+        # Check correct lifetime of the talloc'd data with multiple references
+        lst = []
+        obj = _test_pytalloc.DObject(lambda: lst.append('dead'))
+        ref = _test_pytalloc.reference(obj)
+        del obj
+        gc.collect()
+        self.assertEqual(lst, [])
+        del ref
+        gc.collect()
+        self.assertEqual(lst, ['dead'])
+
+
+if __name__ == '__main__':
+    unittest.TestProgram()
index eb3e13d5af08347a33cb8d2b30e643d332dda442..6d0fe94479e3b80326e4159ad94f035d20dc0db1 100644 (file)
 #include "system/time.h"
 #include <talloc.h>
 
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
 #include "talloc_testsuite.h"
 
 static struct timeval timeval_current(void)
@@ -1701,6 +1705,151 @@ static bool test_memlimit(void)
        return true;
 }
 
+#ifdef HAVE_PTHREAD
+
+#define NUM_THREADS 100
+
+/* Sync variables. */
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;
+static void *intermediate_ptr;
+
+/* Subthread. */
+static void *thread_fn(void *arg)
+{
+       int ret;
+       const char *ctx_name = (const char *)arg;
+       void *sub_ctx = NULL;
+       /*
+        * Do stuff that creates a new talloc hierarchy in
+        * this thread.
+        */
+       void *top_ctx = talloc_named_const(NULL, 0, "top");
+       if (top_ctx == NULL) {
+               return NULL;
+       }
+       sub_ctx = talloc_named_const(top_ctx, 100, ctx_name);
+       if (sub_ctx == NULL) {
+               return NULL;
+       }
+
+       /*
+        * Now transfer a pointer from our hierarchy
+        * onto the intermediate ptr.
+        */
+       ret = pthread_mutex_lock(&mtx);
+       if (ret != 0) {
+               talloc_free(top_ctx);
+               return NULL;
+       }
+       /* Wait for intermediate_ptr to be free. */
+       while (intermediate_ptr != NULL) {
+               ret = pthread_cond_wait(&condvar, &mtx);
+               if (ret != 0) {
+                       talloc_free(top_ctx);
+                       return NULL;
+               }
+       }
+
+       /* and move our memory onto it from our toplevel hierarchy. */
+       intermediate_ptr = talloc_move(NULL, &sub_ctx);
+
+       /* Tell the main thread it's ready for pickup. */
+       pthread_cond_broadcast(&condvar);
+       pthread_mutex_unlock(&mtx);
+
+       talloc_free(top_ctx);
+       return NULL;
+}
+
+/* Main thread. */
+static bool test_pthread_talloc_passing(void)
+{
+       int i;
+       int ret;
+       char str_array[NUM_THREADS][20];
+       pthread_t thread_id;
+       void *mem_ctx;
+
+       /*
+        * Important ! Null tracking breaks threaded talloc.
+        * It *must* be turned off.
+        */
+       talloc_disable_null_tracking();
+
+       printf("test: pthread_talloc_passing\n# PTHREAD TALLOC PASSING\n");
+
+       /* Main thread toplevel context. */
+       mem_ctx = talloc_named_const(NULL, 0, "toplevel");
+       if (mem_ctx == NULL) {
+               printf("failed to create toplevel context\n");
+               return false;
+       }
+
+       /*
+        * Spin off NUM_THREADS threads.
+        * They will use their own toplevel contexts.
+        */
+       for (i = 0; i < NUM_THREADS; i++) {
+               (void)snprintf(str_array[i],
+                               20,
+                               "thread:%d",
+                               i);
+               if (str_array[i] == NULL) {
+                       printf("snprintf %d failed\n", i);
+                       return false;
+               }
+               ret = pthread_create(&thread_id,
+                               NULL,
+                               thread_fn,
+                               str_array[i]);
+               if (ret != 0) {
+                       printf("failed to create thread %d (%d)\n", i, ret);
+                       return false;
+               }
+       }
+
+       printf("Created %d threads\n", NUM_THREADS);
+
+       /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */
+       for (i = 0; i < NUM_THREADS; i++) {
+               ret = pthread_mutex_lock(&mtx);
+               if (ret != 0) {
+                       printf("pthread_mutex_lock %d failed (%d)\n", i, ret);
+                       talloc_free(mem_ctx);
+                       return false;
+               }
+
+               /* Wait for intermediate_ptr to have our data. */
+               while (intermediate_ptr == NULL) {
+                       ret = pthread_cond_wait(&condvar, &mtx);
+                       if (ret != 0) {
+                               printf("pthread_cond_wait %d failed (%d)\n", i,
+                                       ret);
+                               talloc_free(mem_ctx);
+                               return false;
+                       }
+               }
+
+               /* and move it onto our toplevel hierarchy. */
+               (void)talloc_move(mem_ctx, &intermediate_ptr);
+
+               /* Tell the sub-threads we're ready for another. */
+               pthread_cond_broadcast(&condvar);
+               pthread_mutex_unlock(&mtx);
+       }
+
+       CHECK_SIZE("pthread_talloc_passing", mem_ctx, NUM_THREADS * 100);
+#if 1
+       /* Dump the hierarchy. */
+       talloc_report(mem_ctx, stdout);
+#endif
+       talloc_free(mem_ctx);
+       printf("success: pthread_talloc_passing\n");
+       return true;
+}
+#endif
+
 static void test_reset(void)
 {
        talloc_set_log_fn(test_log_stdout);
@@ -1771,6 +1920,10 @@ bool torture_local_talloc(struct torture_context *tctx)
        ret &= test_free_children();
        test_reset();
        ret &= test_memlimit();
+#ifdef HAVE_PTHREAD
+       test_reset();
+       ret &= test_pthread_talloc_passing();
+#endif
 
 
        if (ret) {
similarity index 99%
rename from buildtools/wafadmin/3rdparty/ParallelDebug.py
rename to third_party/waf/wafadmin/3rdparty/ParallelDebug.py
index 9d0493e5e172f8d0dfb4f493cccaa19f14af6087..0ff580ece27c15e179a8c9e4bf751e39585b3ba6 100644 (file)
@@ -295,5 +295,3 @@ function hideInfo(evt) {
        #node = producer.bld.path.make_node('pdebug.svg')
        f = open('pdebug.svg', 'w')
        f.write("".join(out))
-
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/batched_cc.py
rename to third_party/waf/wafadmin/3rdparty/batched_cc.py
index 8e310745c633861db9c1c527cd741ce754d74e87..7ed569ccb709c4302650f53c45c1f55ec0b0cc83 100644 (file)
@@ -180,4 +180,3 @@ for c in ['cc', 'cxx']:
        setattr(t, 'post_run', post_run)
        setattr(t, 'old_can_retrieve_cache', t.can_retrieve_cache)
        setattr(t, 'can_retrieve_cache', can_retrieve_cache)
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/boost.py
rename to third_party/waf/wafadmin/3rdparty/boost.py
index e690a4e2740f0714d67bca0822f5b26d39abf5a9..1cbbf7e850dc9a64bf29b2201431f8bd993f3d83 100644 (file)
@@ -340,4 +340,3 @@ def check_boost(self, *k, **kw):
                                self.check_message_2(kw['okmsg'])
 
        return ret
-
diff --git a/third_party/waf/wafadmin/3rdparty/build_file_tracker.py b/third_party/waf/wafadmin/3rdparty/build_file_tracker.py
new file mode 100644 (file)
index 0000000..5fc7358
--- /dev/null
@@ -0,0 +1,53 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2015
+
+"""
+Force tasks to use file timestamps to force partial rebuilds when touch-ing build files
+
+touch out/libfoo.a
+... rebuild what depends on libfoo.a
+
+to use::
+    def options(opt):
+        opt.tool_options('build_file_tracker')
+"""
+
+import os
+import Task, Utils
+
+def signature(self):
+       try: return self.cache_sig[0]
+       except AttributeError: pass
+
+       self.m = Utils.md5()
+
+       # explicit deps
+       exp_sig = self.sig_explicit_deps()
+
+       # env vars
+       var_sig = self.sig_vars()
+
+       # implicit deps
+       imp_sig = Task.SIG_NIL
+       if self.scan:
+               try:
+                       imp_sig = self.sig_implicit_deps()
+               except ValueError:
+                       return self.signature()
+
+       # timestamp dependency on build files only (source files are hashed)
+       buf = []
+       for k in self.inputs + getattr(self, 'dep_nodes', []) + self.generator.bld.node_deps.get(self.unique_id(), []):
+               if k.id & 3 == 3:
+                       t = os.stat(k.abspath(self.env)).st_mtime
+                       buf.append(t)
+       self.m.update(str(buf))
+
+       # we now have the signature (first element) and the details (for debugging)
+       ret = self.m.digest()
+       self.cache_sig = (ret, exp_sig, imp_sig, var_sig)
+       return ret
+
+Task.Task.signature_bak = Task.Task.signature # unused, kept just in case
+Task.Task.signature = signature # overridden
similarity index 99%
rename from buildtools/wafadmin/3rdparty/fluid.py
rename to third_party/waf/wafadmin/3rdparty/fluid.py
index 117edef7200b62ceb450de51498a9d4a92f348b7..c858fe311cbea7c35cfd68c6d032f5dca09e996c 100644 (file)
@@ -24,4 +24,3 @@ def fluid(self, node):
 def detect(conf):
     fluid = conf.find_program('fluid', var='FLUID', mandatory=True)
     conf.check_cfg(path='fltk-config', package='', args='--cxxflags --ldflags', uselib_store='FLTK', mandatory=True)
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/gccdeps.py
rename to third_party/waf/wafadmin/3rdparty/gccdeps.py
index 6600c9ca3ba563fde3d28061541606e1ab797905..28a889d78b63f400d453de878cde1b7ccf7b8c99 100644 (file)
@@ -125,4 +125,3 @@ for name in 'cc cxx'.split():
                cls.post_run = post_run
                cls.scan = scan
                cls.sig_implicit_deps = sig_implicit_deps
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/go.py
rename to third_party/waf/wafadmin/3rdparty/go.py
index 2d8df0d2b64eba1ea4d14c88830b7da32a599711..f8397c7e1c7fc04ecaddcb79a8b7b544df768676 100644 (file)
@@ -108,4 +108,3 @@ def apply_golink(self):
                        self.path.find_or_declare(self.target))
        self.go_link_task.set_run_after(self.go_compile_task)
        self.go_link_task.dep_nodes.extend(self.go_compile_task.outputs)
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/lru_cache.py
rename to third_party/waf/wafadmin/3rdparty/lru_cache.py
index 5b00abc29bebcff5d07639c0e38c8b7791ba5a46..96f0e6cf10937da30a5257ae5f04f96a0defd446 100644 (file)
@@ -94,4 +94,3 @@ def sweep(self):
 Build.BuildContext.raw_compile = Build.BuildContext.compile
 Build.BuildContext.compile = compile
 Build.BuildContext.sweep = sweep
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/paranoid.py
rename to third_party/waf/wafadmin/3rdparty/paranoid.py
index ead64ea5c3aa80b0c04001aeca1adc8e49151382..ba6d752894949d3c1e7485f126ce219e77023ec5 100644 (file)
@@ -32,4 +32,3 @@ def compile(self):
                check_task_classes(self)
        return comp(self)
 Build.BuildContext.compile = compile
-
diff --git a/third_party/waf/wafadmin/3rdparty/prefork.py b/third_party/waf/wafadmin/3rdparty/prefork.py
new file mode 100755 (executable)
index 0000000..88fb4e4
--- /dev/null
@@ -0,0 +1,275 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2015 (ita)
+#
+# prefer the waf 1.8 version
+
+"""
+The full samba build can be faster by ~10%, but there are a few limitations:
+* only one build process should be run at a time as the servers would use the same ports
+* only one build command is going to be called ("waf build configure build" would not work)
+
+def build(bld):
+
+    mod = Utils.load_tool('prefork')
+    mod.build(bld)
+    ...
+    (build declarations after)
+"""
+
+import os, re, socket, threading, sys, subprocess, time, atexit, traceback
+try:
+       import SocketServer
+except ImportError:
+       import socketserver as SocketServer
+try:
+       from queue import Queue
+except ImportError:
+       from Queue import Queue
+try:
+       import cPickle
+except ImportError:
+       import pickle as cPickle
+
+DEFAULT_PORT = 51200
+
+HEADER_SIZE = 128
+
+REQ = 'REQ'
+RES = 'RES'
+BYE = 'BYE'
+
+def make_header(params):
+       header = ','.join(params)
+       if sys.hexversion > 0x3000000:
+               header = header.encode('iso8859-1')
+       header = header.ljust(HEADER_SIZE)
+       assert(len(header) == HEADER_SIZE)
+       return header
+
+
+re_valid_query = re.compile('^[a-zA-Z0-9_, ]+$')
+class req(SocketServer.StreamRequestHandler):
+       def handle(self):
+               while 1:
+                       try:
+                               self.process_command()
+                       except Exception as e:
+                               print(e)
+                               break
+
+       def process_command(self):
+               query = self.rfile.read(HEADER_SIZE)
+               if not query:
+                       return
+               #print(len(query))
+               assert(len(query) == HEADER_SIZE)
+               if sys.hexversion > 0x3000000:
+                       query = query.decode('iso8859-1')
+               #print "%r" % query
+               if not re_valid_query.match(query):
+                       raise ValueError('Invalid query %r' % query)
+
+               query = query.strip().split(',')
+
+               if query[0] == REQ:
+                       self.run_command(query[1:])
+               elif query[0] == BYE:
+                       raise ValueError('Exit')
+               else:
+                       raise ValueError('Invalid query %r' % query)
+
+       def run_command(self, query):
+
+               size = int(query[0])
+               data = self.rfile.read(size)
+               assert(len(data) == size)
+               kw = cPickle.loads(data)
+
+               # run command
+               ret = out = err = exc = None
+               cmd = kw['cmd']
+               del kw['cmd']
+               #print(cmd)
+
+               try:
+                       if kw['stdout'] or kw['stderr']:
+                               p = subprocess.Popen(cmd, **kw)
+                               (out, err) = p.communicate()
+                               ret = p.returncode
+                       else:
+                               ret = subprocess.Popen(cmd, **kw).wait()
+               except Exception as e:
+                       ret = -1
+                       exc = str(e) + traceback.format_exc()
+
+               # write the results
+               if out or err or exc:
+                       data = (out, err, exc)
+                       data = cPickle.dumps(data, -1)
+               else:
+                       data = ''
+
+               params = [RES, str(ret), str(len(data))]
+
+               self.wfile.write(make_header(params))
+
+               if data:
+                       self.wfile.write(data)
+
+def create_server(conn, cls):
+       #SocketServer.ThreadingTCPServer.allow_reuse_address = True
+       #server = SocketServer.ThreadingTCPServer(conn, req)
+
+       SocketServer.TCPServer.allow_reuse_address = True
+       server = SocketServer.TCPServer(conn, req)
+       #server.timeout = 6000 # seconds
+       server.serve_forever(poll_interval=0.001)
+
+if __name__ == '__main__':
+       if len(sys.argv) > 1:
+               port = int(sys.argv[1])
+       else:
+               port = DEFAULT_PORT
+       #conn = (socket.gethostname(), port)
+       conn = ("127.0.0.1", port)
+       #print("listening - %r %r\n" % conn)
+       create_server(conn, req)
+else:
+
+       import Runner, Utils
+
+       def init_task_pool(self):
+               # lazy creation, and set a common pool for all task consumers
+               pool = self.pool = []
+               for i in range(self.numjobs):
+                       consumer = Runner.get_pool()
+                       pool.append(consumer)
+                       consumer.idx = i
+               self.ready = Queue(0)
+               def setq(consumer):
+                       consumer.ready = self.ready
+                       try:
+                               threading.current_thread().idx = consumer.idx
+                       except Exception as e:
+                               print(e)
+               for x in pool:
+                       x.ready.put(setq)
+               return pool
+       Runner.Parallel.init_task_pool = init_task_pool
+
+       PORT = 51200
+
+       def make_server(idx):
+               port = PORT + idx
+               cmd = [sys.executable, os.path.abspath(__file__), str(port)]
+               proc = subprocess.Popen(cmd)
+               proc.port = port
+               return proc
+
+       def make_conn(srv):
+               #port = PORT + idx
+               port = srv.port
+               conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+               conn.connect(('127.0.0.1', port))
+               return conn
+
+       SERVERS = []
+       CONNS = []
+       def close_all():
+               while CONNS:
+                       conn = CONNS.pop()
+                       try:
+                               conn.close()
+                       except:
+                               pass
+               while SERVERS:
+                       srv = SERVERS.pop()
+                       try:
+                               srv.kill()
+                       except:
+                               pass
+       atexit.register(close_all)
+
+       def put_data(conn, data):
+               conn.send(data)
+
+       def read_data(conn, siz):
+               ret = conn.recv(siz)
+               if not ret:
+                       print("closed connection?")
+
+               assert(len(ret) == siz)
+               return ret
+
+       def exec_command(cmd, **kw):
+               if 'log' in kw:
+                       log = kw['log']
+                       kw['stdout'] = kw['stderr'] = subprocess.PIPE
+                       del(kw['log'])
+               else:
+                       kw['stdout'] = kw['stderr'] = None
+               kw['shell'] = isinstance(cmd, str)
+
+               idx = threading.current_thread().idx
+               kw['cmd'] = cmd
+
+               data = cPickle.dumps(kw, -1)
+               params = [REQ, str(len(data))]
+               header = make_header(params)
+
+               conn = CONNS[idx]
+
+               put_data(conn, header)
+               put_data(conn, data)
+
+               data = read_data(conn, HEADER_SIZE)
+               if sys.hexversion > 0x3000000:
+                       data = data.decode('iso8859-1')
+
+               lst = data.split(',')
+               ret = int(lst[1])
+               dlen = int(lst[2])
+
+               out = err = None
+               if dlen:
+                       data = read_data(conn, dlen)
+                       (out, err, exc) = cPickle.loads(data)
+                       if exc:
+                               raise Utils.WafError('Execution failure: %s' % exc)
+
+               if out:
+                       log.write(out)
+               if err:
+                       log.write(err)
+
+               return ret
+
+       def __init__(self):
+               threading.Thread.__init__(self)
+
+               # identifier of the current thread
+               self.idx = len(SERVERS)
+
+               # create a server and wait for the connection
+               srv = make_server(self.idx)
+               SERVERS.append(srv)
+
+               conn = None
+               for x in range(30):
+                       try:
+                               conn = make_conn(srv)
+                               break
+                       except socket.error:
+                               time.sleep(0.01)
+               if not conn:
+                       raise ValueError('Could not start the server!')
+               CONNS.append(conn)
+
+               self.setDaemon(1)
+               self.start()
+       Runner.TaskConsumer.__init__ = __init__
+
+       def build(bld):
+               # dangerous, there is no other command hopefully
+               Utils.exec_command = exec_command
similarity index 99%
rename from buildtools/wafadmin/3rdparty/swig.py
rename to third_party/waf/wafadmin/3rdparty/swig.py
index c0a4108700e72b6e082f166d7dbdf4442b3576db..393e8e190a09e2e81cc3dc7adc07fa21947fdd4b 100644 (file)
@@ -187,4 +187,3 @@ def check_swig_version(conf, minver=None):
 
 def detect(conf):
        swig = conf.find_program('swig', var='SWIG', mandatory=True)
-
similarity index 99%
rename from buildtools/wafadmin/3rdparty/valadoc.py
rename to third_party/waf/wafadmin/3rdparty/valadoc.py
index d0a9fe80ed64efac9d08773b47a1b2c21e67099b..bdb0c6bd5b8f2f6c954456ad9e45fe494350d37c 100644 (file)
@@ -110,4 +110,3 @@ def process_valadoc(self):
 
 def detect(conf):
   conf.find_program('valadoc', var='VALADOC', mandatory=False)
-
similarity index 99%
rename from buildtools/wafadmin/Build.py
rename to third_party/waf/wafadmin/Build.py
index 8e7c72c4ed709f0e2c0a41e785610a418a4b67bd..50f4d7f6c69e949ddb7a89b4760063d90aea4b0e 100644 (file)
@@ -1030,4 +1030,3 @@ class BuildContext(Utils.Context):
        install_as = group_method(install_as)
        install_files = group_method(install_files)
        symlink_as = group_method(symlink_as)
-
similarity index 99%
rename from buildtools/wafadmin/Configure.py
rename to third_party/waf/wafadmin/Configure.py
index 35b4e51ec35a09721fbcf32e086e475022272e9f..7575cefd0e194fee795d0a1720c17fcf62c829b2 100644 (file)
@@ -440,5 +440,3 @@ def conftest(f):
        "decorator: attach new configuration tests (registered as strings)"
        ConfigurationContext.tests[f.__name__] = f
        return conf(f)
-
-
similarity index 99%
rename from buildtools/wafadmin/Constants.py
rename to third_party/waf/wafadmin/Constants.py
index e67dda6ecd8c235cf5ae782fd696d9dca3ccf5ec..30960b978d1b584214cbc7cdb5fa4eda915e536f 100644 (file)
@@ -73,4 +73,3 @@ CFG_FILES = 'cfg_files'
 # negative '<-' uninstall
 INSTALL = 1337
 UNINSTALL = -1337
-
similarity index 99%
rename from buildtools/wafadmin/Environment.py
rename to third_party/waf/wafadmin/Environment.py
index 52c83b4f3e45b543563e5777b0d3c38a706ffe98..bea4146516568e51ce2e91bb934141ae558f6935 100644 (file)
@@ -207,4 +207,3 @@ class Environment(object):
                        object.__delattr__(self, name)
                else:
                        del self[name]
-
similarity index 99%
rename from buildtools/wafadmin/Logs.py
rename to third_party/waf/wafadmin/Logs.py
index c160b3773664aa8b06db9a5a351d852a41b50ada..f67e87c721281910bb1f3a5049fd724a9b9e07da 100644 (file)
@@ -131,4 +131,3 @@ def init_log():
 
 # may be initialized more than once
 init_log()
-
similarity index 99%
rename from buildtools/wafadmin/Node.py
rename to third_party/waf/wafadmin/Node.py
index 236dd0d2b3f5ee044bb4a31eda439dd8840a4846..158a4a4d47010d3e2f32fe759d678c028f4234df 100644 (file)
@@ -663,7 +663,7 @@ class Node(object):
        def update_build_dir(self, env=None):
 
                if not env:
-                       for env in bld.all_envs:
+                       for env in self.bld.all_envs:
                                self.update_build_dir(env)
                        return
 
@@ -692,4 +692,3 @@ class Node(object):
 
 class Nodu(Node):
        pass
-
similarity index 99%
rename from buildtools/wafadmin/Options.py
rename to third_party/waf/wafadmin/Options.py
index c9ddcfe650314edb38d4aef6cb1b60d4ca1dc7b3..7e87c110902842269e3e063d1c8c3031e88a33c8 100644 (file)
@@ -285,4 +285,3 @@ class Handler(Utils.Context):
 
        def parse_args(self, args=None):
                parse_args_impl(self.parser, args)
-
similarity index 99%
rename from buildtools/wafadmin/Runner.py
rename to third_party/waf/wafadmin/Runner.py
index 94db0fbd1ba4d5f0879ef27da6f7250f36b400b6..0d2dea5ef47c5fc926891d8ea63c9e42e527fc51 100644 (file)
@@ -233,4 +233,3 @@ class Parallel(object):
 
                #print loop
                assert (self.count == 0 or self.stop)
-
similarity index 99%
rename from buildtools/wafadmin/Scripting.py
rename to third_party/waf/wafadmin/Scripting.py
index d975bd934d13c793a2efe2c38941d511226c64d7..6f6110487db9279d871cefba625c3b72fb21ad22 100644 (file)
@@ -583,4 +583,3 @@ def distcheck(appname='', version='', subdir=''):
 # FIXME remove in Waf 1.6 (kept for compatibility)
 def add_subdir(dir, bld):
        bld.recurse(dir, 'build')
-
similarity index 99%
rename from buildtools/wafadmin/Task.py
rename to third_party/waf/wafadmin/Task.py
index 5cda2ec7301f592f3b5afa0c593eb2f9118077a5..59d10203a496d157f3c8c97b11c1185040d359e6 100644 (file)
@@ -1197,4 +1197,3 @@ def extract_deps(tasks):
                        delattr(x, 'cache_sig')
                except AttributeError:
                        pass
-
similarity index 98%
rename from buildtools/wafadmin/TaskGen.py
rename to third_party/waf/wafadmin/TaskGen.py
index ae1834a10a4212c4e533ab5e32045c1519e82734..5900809ddfed4692fd8e61bb7b9df03ec7a665c9 100644 (file)
@@ -291,8 +291,8 @@ class task_gen(object):
                else: self.source += lst
 
        def clone(self, env):
-               """when creating a clone in a task generator method, 
-               make sure to set posted=False on the clone 
+               """when creating a clone in a task generator method,
+               make sure to set posted=False on the clone
                else the other task generator will not create its tasks"""
                newobj = task_gen(bld=self.bld)
                for x in self.__dict__:
@@ -567,7 +567,7 @@ def exec_rule(self):
        if getattr(self, 'cwd', None):
                tsk.cwd = self.cwd
 
-       if getattr(self, 'on_results', None):
+       if getattr(self, 'on_results', None) or getattr(self, 'update_outputs', None):
                Task.update_outputs(cls)
 
        if getattr(self, 'always', None):
@@ -609,4 +609,3 @@ def sequence_order(self):
        self.bld.prev = self
 
 feature('seq')(sequence_order)
-
similarity index 98%
rename from buildtools/wafadmin/Tools/__init__.py
rename to third_party/waf/wafadmin/Tools/__init__.py
index bc6ca230b5e9fb455e21ce0b19f0e3456ed26694..8f026e187ff6e3a2d9d3bf02bc34329a510767f5 100644 (file)
@@ -1,4 +1,3 @@
 #!/usr/bin/env python
 # encoding: utf-8
 # Thomas Nagy, 2006 (ita)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/ar.py
rename to third_party/waf/wafadmin/Tools/ar.py
index af9b17fd6e99e2a9ea2a2c84c07ce08bef2d902f..3571670d5b50ecd4e18381ff03e1f95a557ec842 100644 (file)
@@ -32,5 +32,3 @@ def find_ar(conf):
        v = conf.env
        conf.check_tool('ar')
        if not v['AR']: conf.fatal('ar is required for static libraries - not found')
-
-
similarity index 99%
rename from buildtools/wafadmin/Tools/bison.py
rename to third_party/waf/wafadmin/Tools/bison.py
index 49c605187336c254e740eca143a0fe3bafd1341e..c281e61ddaffc86e154aa8b0f7730ac4e47c0f63 100644 (file)
@@ -35,4 +35,3 @@ def big_bison(self, node):
 def detect(conf):
        bison = conf.find_program('bison', var='BISON', mandatory=True)
        conf.env['BISONFLAGS'] = '-d'
-
similarity index 99%
rename from buildtools/wafadmin/Tools/cc.py
rename to third_party/waf/wafadmin/Tools/cc.py
index 903a1c5038c80499c5bef7d969c8696856e995c3..e54df4715e5d80d0600887b08ae52c6f94898b96 100644 (file)
@@ -97,4 +97,3 @@ link_str = '${LINK_CC} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath(env)}
 cls = Task.simple_task_type('cc_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False)
 cls.maxjobs = 1
 cls.install = Utils.nada
-
similarity index 99%
rename from buildtools/wafadmin/Tools/ccroot.py
rename to third_party/waf/wafadmin/Tools/ccroot.py
index 25c5179be0e08581c75024fafcaff0a71d22a724..c130b40a21dc52b6c3a8063f3f3f0e3f7aef11f9 100644 (file)
@@ -637,4 +637,3 @@ cls.quiet = 1
 def add_as_needed(conf):
        if conf.env.DEST_BINFMT == 'elf' and 'gcc' in (conf.env.CXX_NAME, conf.env.CC_NAME):
                conf.env.append_unique('LINKFLAGS', '--as-needed')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/compiler_cc.py
rename to third_party/waf/wafadmin/Tools/compiler_cc.py
index 0421503f7c932ba65b6b10c39c0ffb647a40c619..642458aba61344451201c9dc629a4271bb1bfb89 100644 (file)
@@ -64,4 +64,3 @@ def set_options(opt):
 
        for c_compiler in test_for_compiler.split():
                opt.tool_options('%s' % c_compiler, option_group=cc_compiler_opts)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/compiler_cxx.py
rename to third_party/waf/wafadmin/Tools/compiler_cxx.py
index 5308ea97199e04f028d380157d8217b0ab29ac10..aa0b0e7d460a3ab8d2dda8aa770218d83bd3b624 100644 (file)
@@ -59,4 +59,3 @@ def set_options(opt):
 
        for cxx_compiler in test_for_compiler.split():
                opt.tool_options('%s' % cxx_compiler, option_group=cxx_compiler_opts)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/compiler_d.py
rename to third_party/waf/wafadmin/Tools/compiler_d.py
index 1ea5efa30e8b4ba7cd24b4bd1352724db246ba16..378277a25aaa8de6d3f7816e8c56ac17e7f3a825 100644 (file)
@@ -30,4 +30,3 @@ def set_options(opt):
 
        for d_compiler in ['gdc', 'dmd']:
                opt.tool_options('%s' % d_compiler, option_group=d_compiler_opts)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/config_c.py
rename to third_party/waf/wafadmin/Tools/config_c.py
index d0bc61773625576cec1d0b1eec2635086d04c2e7..9f1103cb27d58e8b0cd3cf6aca345bbec990b6e8 100644 (file)
@@ -746,4 +746,3 @@ def cc_load_tools(conf):
 @conftest
 def cxx_load_tools(conf):
        conf.check_tool('cxx')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/cs.py
rename to third_party/waf/wafadmin/Tools/cs.py
index 43544856f34045ede3b6c3f4680d87b0d5c94794..4c987d2a875f846d24032020293222e4152eef1c 100644 (file)
@@ -65,4 +65,3 @@ def detect(conf):
 
 def set_options(opt):
        opt.add_option('--with-csc-binary', type='string', dest='cscbinary')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/cxx.py
rename to third_party/waf/wafadmin/Tools/cxx.py
index 719b82177c15e189ae15afde994e5cc38fda6bcf..184fee3e0654a5195ddadd7e76a1fa686ed6ef41 100644 (file)
@@ -101,4 +101,3 @@ link_str = '${LINK_CXX} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath(en
 cls = Task.simple_task_type('cxx_link', link_str, color='YELLOW', ext_in='.o', ext_out='.bin', shell=False)
 cls.maxjobs = 1
 cls.install = Utils.nada
-
similarity index 99%
rename from buildtools/wafadmin/Tools/d.py
rename to third_party/waf/wafadmin/Tools/d.py
index 1a22821bc5561511ff59fe2e4c49705b6aaf2f24..2c2e94857e36a52fd619a6415b62392f6147dd8e 100644 (file)
@@ -532,4 +532,3 @@ if __name__ == "__main__":
                print imp + " ",
        print
 """
-
similarity index 99%
rename from buildtools/wafadmin/Tools/dbus.py
rename to third_party/waf/wafadmin/Tools/dbus.py
index 317999939213f08ce61428cf8424c875fe77c890..42c4ca2cb7fb29d64de074911b67aa873c7cf479 100644 (file)
@@ -31,4 +31,3 @@ Task.simple_task_type('dbus_binding_tool',
 
 def detect(conf):
        dbus_binding_tool = conf.find_program('dbus-binding-tool', var='DBUS_BINDING_TOOL')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/dmd.py
rename to third_party/waf/wafadmin/Tools/dmd.py
index 9c7490844db04328b81d34cc72c921f8a25c4758..b86ffd6a0f41c502d6128995319eb53c4122abad 100644 (file)
@@ -61,4 +61,3 @@ def detect(conf):
 
        if conf.env.D_COMPILER.find('ldc') > -1:
                conf.common_flags_ldc()
-
similarity index 99%
rename from buildtools/wafadmin/Tools/flex.py
rename to third_party/waf/wafadmin/Tools/flex.py
index 5ce9f2210e380b01ca56a7aa5271e31c03edd672..cbea42db2c94170628a6713e9499722170bf4b28 100644 (file)
@@ -22,4 +22,3 @@ TaskGen.declare_chain(
 def detect(conf):
        conf.find_program('flex', var='FLEX', mandatory=True)
        conf.env['FLEXFLAGS'] = ''
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gas.py
rename to third_party/waf/wafadmin/Tools/gas.py
index c983b0a39591c2e2c35384726729e93aad2494f5..5dd0b5d746077b6aa9daaaa17f251a63e361d5f4 100644 (file)
@@ -35,4 +35,3 @@ def detect(conf):
        conf.find_program(['gas', 'as'], var='AS')
        if not conf.env.AS: conf.env.AS = conf.env.CC
        #conf.env.ASFLAGS = ['-c'] <- may be necesary for .S files
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gcc.py
rename to third_party/waf/wafadmin/Tools/gcc.py
index a6be0b28dbf133097d69798d5bc7eefc92af4c16..83d5b248ad9ff091533b64ad494784e4c439503b 100644 (file)
@@ -136,4 +136,3 @@ def detect(conf):
        conf.cc_load_tools()
        conf.cc_add_flags()
        conf.link_add_flags()
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gdc.py
rename to third_party/waf/wafadmin/Tools/gdc.py
index 4d2a3216edd5a11cb9830a67b593968d0f82b6cb..d1e5e7b53cb720ca2c429ac730bf5af6498684a4 100644 (file)
@@ -49,4 +49,3 @@ def detect(conf):
        conf.check_tool('d')
        conf.common_flags_gdc()
        conf.d_platform_flags()
-
similarity index 99%
rename from buildtools/wafadmin/Tools/glib2.py
rename to third_party/waf/wafadmin/Tools/glib2.py
index 042d612cbe48cf66c7cf0df86cdfe69b8a2d0e5e..d3fc7769740967ca0c79eaf8a36e1bac76d88548 100644 (file)
@@ -161,4 +161,3 @@ Task.simple_task_type('glib_mkenums',
 def detect(conf):
        glib_genmarshal = conf.find_program('glib-genmarshal', var='GLIB_GENMARSHAL')
        mk_enums_tool = conf.find_program('glib-mkenums', var='GLIB_MKENUMS')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gnome.py
rename to third_party/waf/wafadmin/Tools/gnome.py
index c098a41bb4b60d9ee9d335fec3e9f2576e8ea32c..da11e91d3d87a320584869c25929ec8ba18cc6c2 100644 (file)
@@ -220,4 +220,3 @@ def detect(conf):
 
 def set_options(opt):
        opt.add_option('--want-rpath', type='int', default=1, dest='want_rpath', help='set rpath to 1 or 0 [Default 1]')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gnu_dirs.py
rename to third_party/waf/wafadmin/Tools/gnu_dirs.py
index 856e4a7204b54421b5346131c376bfe7dbd53a51..ac149dfa46b8a124e151c2494bd47e6a4b35c15b 100644 (file)
@@ -108,4 +108,3 @@ def set_options(opt):
                str_default = default
                str_help = '%s [Default: %s]' % (help, str_default)
                dirs_options.add_option(option_name, help=str_help, default='', dest=name.upper())
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gob2.py
rename to third_party/waf/wafadmin/Tools/gob2.py
index 00aaa32acda1a1da0e91850944f4242de8e6acd0..96d8e2030ca959be7b783bede30b359d8862f291 100644 (file)
@@ -15,4 +15,3 @@ def detect(conf):
        gob2 = conf.find_program('gob2', var='GOB2', mandatory=True)
        conf.env['GOB2'] = gob2
        conf.env['GOB2FLAGS'] = ''
-
similarity index 99%
rename from buildtools/wafadmin/Tools/gxx.py
rename to third_party/waf/wafadmin/Tools/gxx.py
index 4984122e5e6239cb2e462fbca06dd710f134432c..38e8d00ae5b4a4ed4b58c36bc7d2d8cd0eaa57c7 100644 (file)
@@ -100,7 +100,7 @@ def gxx_modifier_darwin(conf):
 
        v['SHLIB_MARKER']        = ''
        v['STATICLIB_MARKER']    = ''
-       v['SONAME_ST']           = ''   
+       v['SONAME_ST']           = ''
 
 @conftest
 def gxx_modifier_aix(conf):
@@ -134,4 +134,3 @@ def detect(conf):
        conf.cxx_load_tools()
        conf.cxx_add_flags()
        conf.link_add_flags()
-
similarity index 99%
rename from buildtools/wafadmin/Tools/intltool.py
rename to third_party/waf/wafadmin/Tools/intltool.py
index deb8f4a634149cec3a50799f3674cf376d69dab9..5fb3df2cbbb89ddd7d93dc24d103fa9a4356ab24 100644 (file)
@@ -136,4 +136,3 @@ def detect(conf):
 def set_options(opt):
        opt.add_option('--want-rpath', type='int', default=1, dest='want_rpath', help='set rpath to 1 or 0 [Default 1]')
        opt.add_option('--datadir', type='string', default='', dest='datadir', help='read-only application data')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/javaw.py
rename to third_party/waf/wafadmin/Tools/javaw.py
index 301ebc426b9d23a1b62b31c11042225ce2d1fbe3..4d9f4c77907c0136fa4e1280a9c2c7388c69cc89 100644 (file)
@@ -252,4 +252,3 @@ def check_jni_headers(conf):
                        break
        else:
                conf.fatal('could not find lib jvm in %r (see config.log)' % libDirs)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/kde4.py
rename to third_party/waf/wafadmin/Tools/kde4.py
index f480929da653d11a5d9c1efca8d8296094af3ae0..1f3bae783d38cd6cacb570548d40965c818f5cc8 100644 (file)
@@ -71,4 +71,3 @@ def detect(conf):
        conf.env['MSGFMT'] = conf.find_program('msgfmt')
 
 Task.simple_task_type('msgfmt', '${MSGFMT} ${SRC} -o ${TGT}', color='BLUE', shell=False)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/libtool.py
rename to third_party/waf/wafadmin/Tools/libtool.py
index 47fa906fcccb2ca2d0decc72a80cebd77681e883..bcc0e2f318d13b2da6de7206333bc689ef241852 100644 (file)
@@ -327,4 +327,3 @@ nor: %prog --libs /usr/lib/libamarok.la'''
 
 if __name__ == '__main__':
        useCmdLine()
-
similarity index 99%
rename from buildtools/wafadmin/Tools/lua.py
rename to third_party/waf/wafadmin/Tools/lua.py
index 5b181e1310fbc065aa40fdb6e24aec2f8d756e4e..8a6c1f46e796ca4f71e0f053f7a2666ea9339e6b 100644 (file)
@@ -22,4 +22,3 @@ def init_lua(self):
 
 def detect(conf):
        conf.find_program('luac', var='LUAC', mandatory = True)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/misc.py
rename to third_party/waf/wafadmin/Tools/misc.py
index 9903ee4bd3cad59e05f75ae5548b1d0b5622ef7e..6ef45aef444b74096442a8f086ea45fb247a2a0f 100644 (file)
@@ -427,4 +427,3 @@ def runnable_status(self):
 
 Task.task_type_from_func('copy', vars=[], func=action_process_file_func)
 TaskGen.task_gen.classes['command-output'] = cmd_output_taskgen
-
similarity index 99%
rename from buildtools/wafadmin/Tools/msvc.py
rename to third_party/waf/wafadmin/Tools/msvc.py
index 4fde8b14687999cc6d49d232d4f99626408417f5..2a97d19a7ebca93a9529575594470f29db677c29 100644 (file)
@@ -729,15 +729,15 @@ def exec_mf(self):
        self.do_manifest = False
 
        outfile = self.outputs[0].bldpath(env)
-       
+
        manifest = None
        for out_node in self.outputs:
                if out_node.name.endswith('.manifest'):
                        manifest = out_node.bldpath(env)
                        break
        if manifest is None:
-               # Should never get here.  If we do, it means the manifest file was 
-               # never added to the outputs list, thus we don't have a manifest file 
+               # Should never get here.  If we do, it means the manifest file was
+               # never added to the outputs list, thus we don't have a manifest file
                # to embed, so we just return.
                return 0
 
@@ -794,4 +794,3 @@ for k in 'cc cxx winrc cc_link cxx_link static_link qxx'.split():
        cls = Task.TaskBase.classes.get(k, None)
        if cls:
                cls.exec_command = exec_command_msvc
-
similarity index 95%
rename from buildtools/wafadmin/Tools/nasm.py
rename to third_party/waf/wafadmin/Tools/nasm.py
index b99c3c7340460f51433c2aa982b4ac8827213a46..43b73a7e4839a13887f90bc5bb0ec46e751c3fb7 100644 (file)
@@ -36,7 +36,7 @@ def nasm_file(self, node):
        try: obj_ext = self.obj_ext
        except AttributeError: obj_ext = '_%d.o' % self.idx
 
-       task = self.create_task('nasm', node, node.change_ext(obj_ext))
+       task = self.create_task('nasm', node, node.change_ext(obj_ext))
        self.compiled_tasks.append(task)
 
        self.meths.append('apply_nasm_vars')
@@ -46,4 +46,3 @@ Task.simple_task_type('nasm', nasm_str, color='BLUE', ext_out='.o', shell=False)
 
 def detect(conf):
        nasm = conf.find_program(['nasm', 'yasm'], var='NASM', mandatory=True)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/ocaml.py
rename to third_party/waf/wafadmin/Tools/ocaml.py
index 20c926969a129b61604a45d16d09fbe2f8560309..a0667a4d257e55fdbef012bb8a560859aef9d21e 100644 (file)
@@ -295,4 +295,3 @@ def detect(conf):
        v['LIBPATH_OCAML'] = Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep
        v['CPPPATH_OCAML'] = Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep
        v['LIB_OCAML'] = 'camlrun'
-
similarity index 99%
rename from buildtools/wafadmin/Tools/osx.py
rename to third_party/waf/wafadmin/Tools/osx.py
index 561eca487dedf329513d59d8a95b780f5874bc8f..88ca0d950aa9d672c53864cdefad81516076e048 100644 (file)
@@ -185,4 +185,3 @@ def plist_build(task):
 
 Task.task_type_from_func('macapp', vars=[], func=app_build, after="cxx_link cc_link static_link")
 Task.task_type_from_func('macplist', vars=[], func=plist_build, after="cxx_link cc_link static_link")
-
similarity index 99%
rename from buildtools/wafadmin/Tools/perl.py
rename to third_party/waf/wafadmin/Tools/perl.py
index a6787a86ecfa86d41593fb01c561e145d6825738..85105ead88fd9f5863fa442aa6397a1acfd59207 100644 (file)
@@ -106,4 +106,3 @@ def check_perl_ext_devel(conf):
 def set_options(opt):
        opt.add_option("--with-perl-binary", type="string", dest="perlbinary", help = 'Specify alternate perl binary', default=None)
        opt.add_option("--with-perl-archdir", type="string", dest="perlarchdir", help = 'Specify directory where to install arch specific files', default=None)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/preproc.py
rename to third_party/waf/wafadmin/Tools/preproc.py
index 6c49326ec3e5945137972c5fab97226291e1118c..71eb05ae09292e7acdf9decad758d679d84e5130 100644 (file)
@@ -835,5 +835,3 @@ def get_deps_simple(node, env, nodepaths=[], defines={}):
 
        find_deps(node)
        return (nodes, names)
-
-
similarity index 97%
rename from buildtools/wafadmin/Tools/python.py
rename to third_party/waf/wafadmin/Tools/python.py
index 35c61c24664ecac5522b937c33c75e3d14038660..cd96b658185273ef211b2feb4f7039896cfc7688 100644 (file)
@@ -170,10 +170,10 @@ def check_python_headers(conf, mandatory=True):
 
        try:
                # Get some python configuration variables using distutils
-               v = 'prefix SO SYSLIBS LDFLAGS SHLIBS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET'.split()
+               v = 'prefix SO SYSLIBS LDFLAGS SHLIBS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDVERSION'.split()
                (python_prefix, python_SO, python_SYSLIBS, python_LDFLAGS, python_SHLIBS,
                 python_LIBDIR, python_LIBPL, INCLUDEPY, Py_ENABLE_SHARED,
-                python_MACOSX_DEPLOYMENT_TARGET) = \
+                python_MACOSX_DEPLOYMENT_TARGET, python_LDVERSION) = \
                        _get_python_variables(python, ["get_config_var('%s') or ''" % x for x in v],
                                              ['from distutils.sysconfig import get_config_var'])
        except RuntimeError:
@@ -190,8 +190,10 @@ python_LIBPL = %r
 INCLUDEPY = %r
 Py_ENABLE_SHARED = %r
 MACOSX_DEPLOYMENT_TARGET = %r
+LDVERSION = %r
 """ % (python, python_prefix, python_SO, python_SYSLIBS, python_LDFLAGS, python_SHLIBS,
-       python_LIBDIR, python_LIBPL, INCLUDEPY, Py_ENABLE_SHARED, python_MACOSX_DEPLOYMENT_TARGET))
+       python_LIBDIR, python_LIBPL, INCLUDEPY, Py_ENABLE_SHARED, python_MACOSX_DEPLOYMENT_TARGET,
+       python_LDVERSION))
 
        # Allow some python overrides from env vars for cross-compiling
        os_env = dict(os.environ)
@@ -230,7 +232,9 @@ MACOSX_DEPLOYMENT_TARGET = %r
                parse_flags(python_LDFLAGS, 'PYEMBED', env)
 
        result = False
-       name = 'python' + env['PYTHON_VERSION']
+       if not python_LDVERSION:
+               python_LDVERSION = env['PYTHON_VERSION']
+       name = 'python' + python_LDVERSION
 
        if python_LIBDIR is not None:
                path = [python_LIBDIR]
@@ -245,7 +249,7 @@ MACOSX_DEPLOYMENT_TARGET = %r
        if not result:
                conf.log.write("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
                path = [os.path.join(python_prefix, "libs")]
-               name = 'python' + env['PYTHON_VERSION'].replace('.', '')
+               name = 'python' + python_LDVERSION.replace('.', '')
                result = conf.check(lib=name, uselib='PYEMBED', libpath=path)
 
        if result:
@@ -426,4 +430,3 @@ def set_options(opt):
                        default=1,
                        help='Do not install optimised compiled .pyo files (configuration) [Default:install]',
                        dest='pyo')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/qt4.py
rename to third_party/waf/wafadmin/Tools/qt4.py
index 84d121a844f16439ed8c691c01e851efe371323c..7d2cad7d9c1836e66de716ace0307bbcc548e0bc 100644 (file)
@@ -502,4 +502,3 @@ def set_options(opt):
                opt.add_option('--no-qt4-framework', action="store_false", help='do not use the framework version of Qt4 in OS X', dest='use_qt4_osxframework',default=True)
 
        opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False)
-
similarity index 99%
rename from buildtools/wafadmin/Tools/ruby.py
rename to third_party/waf/wafadmin/Tools/ruby.py
index d3b75695aeccd791daebd6497c3f20634c162678..afa8a596b0d8864984ca143b84ef7581f0239f9a 100644 (file)
@@ -117,4 +117,3 @@ def set_options(opt):
        opt.add_option('--with-ruby-archdir', type='string', dest='rubyarchdir', help='Specify directory where to install arch specific files')
        opt.add_option('--with-ruby-libdir', type='string', dest='rubylibdir', help='Specify alternate ruby library path')
        opt.add_option('--with-ruby-binary', type='string', dest='rubybinary', help='Specify alternate ruby binary')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/tex.py
rename to third_party/waf/wafadmin/Tools/tex.py
index 2dd748b23205d4d8a482091d2c4cada7f9a6bccc..43aee1f42714ddfdcfb00ad8520f310fda8cffdd 100644 (file)
@@ -154,7 +154,7 @@ def tex_build(task, command='LATEX'):
                task.env.SRCFILE = srcfile
                ret = fun(task)
                if ret:
-                       error('error when calling %s %s' % (command, latex_compile_cmd))
+                       error('error when calling %s %s' % (command, latex_fun))
                        return ret
 
        return None # ok
@@ -248,4 +248,3 @@ cls = b('latex', latex_build, vars=latex_vardeps)
 cls.scan = scan
 cls = b('pdflatex', pdflatex_build, vars=pdflatex_vardeps)
 cls.scan = scan
-
similarity index 99%
rename from buildtools/wafadmin/Tools/unittestw.py
rename to third_party/waf/wafadmin/Tools/unittestw.py
index 0e30a510fb54cfa16d1ef11c203308f8a74bf2f3..7cf2ded9918167ee51fafb0d5fa0e645d82920b4 100644 (file)
@@ -306,5 +306,3 @@ def summary(bld):
                for (f, code, out, err) in lst:
                        if code:
                                Utils.pprint('CYAN', '    %s' % f)
-
-
similarity index 99%
rename from buildtools/wafadmin/Tools/vala.py
rename to third_party/waf/wafadmin/Tools/vala.py
index 753ee8d94e283aa36cbf71d70f72aaebad532630..df1d11bb83932fc0679c8410ca0e5fac9680b804 100644 (file)
@@ -305,4 +305,3 @@ def set_options (opt):
        valaopts.add_option ('--vala-target-glib', default=None,
                             dest='vala_target_glib', metavar='MAJOR.MINOR',
                             help='Target version of glib for Vala GObject code generation')
-
similarity index 99%
rename from buildtools/wafadmin/Tools/winres.py
rename to third_party/waf/wafadmin/Tools/winres.py
index 2500d431de9000edf1ca53c8ad7ffcfa48b276f2..6b5aad004cc4522347a48d7e10dbdc8a16d39fa4 100644 (file)
@@ -42,4 +42,3 @@ def detect(conf):
                conf.fatal('winrc was not found!')
 
        v['WINRCFLAGS'] = ''
-
similarity index 99%
rename from buildtools/wafadmin/Utils.py
rename to third_party/waf/wafadmin/Utils.py
index 91ded93b6e7d0ef194b2166e3d773b3f9fe7e8e5..5a59a4c30a360951ef99924317f28a0a5ded86d6 100644 (file)
@@ -416,15 +416,15 @@ def pprint(col, str, label='', sep='\n'):
        "print messages in color"
        sys.stderr.write("%s%s%s %s%s" % (Logs.colors(col), str, Logs.colors.NORMAL, label, sep))
 
-def check_dir(dir):
+def check_dir(path):
        """If a folder doesn't exists, create it."""
-       try:
-               os.lstat(dir)
-       except OSError:
+       if not os.path.isdir(path):
                try:
-                       os.makedirs(dir)
+                       os.makedirs(path)
                except OSError, e:
-                       raise WafError("Cannot create folder '%s' (original error: %s)" % (dir, e))
+                       if not os.path.isdir(path):
+                               raise Errors.WafError('Cannot create the folder %r' % path, ex=e)
+
 
 def cmd_output(cmd, **kw):
 
@@ -723,4 +723,3 @@ def run_once(fun):
                        return ret
        wrap.__cache__ = cache
        return wrap
-
similarity index 99%
rename from buildtools/wafadmin/ansiterm.py
rename to third_party/waf/wafadmin/ansiterm.py
index 720b79c53587f785a34329c0bd72c6072875cea4..2ec0b4c964061296e76167baa21004a4035deb9e 100644 (file)
@@ -233,4 +233,3 @@ else:
 
        sys.stderr = sys.stdout = AnsiTerm()
        os.environ['TERM'] = 'vt100'
-
similarity index 99%
rename from buildtools/wafadmin/pproc.py
rename to third_party/waf/wafadmin/pproc.py
index cb15178b4eb92737cfc24fb7866da20778e6956e..44b9dd2f260c58565a105a5e16f9542759b0afeb 100644 (file)
@@ -617,4 +617,3 @@ class Popen(object):
 
             self.wait()
             return (stdout, stderr)
-
similarity index 99%
rename from buildtools/wafadmin/py3kfixes.py
rename to third_party/waf/wafadmin/py3kfixes.py
index 2f3c9c29776548171dd2eae6a16ffb0e6a79e0e8..1a647062e7b7138a4aa47fc1a0a6c4985ea81014 100644 (file)
@@ -127,4 +127,3 @@ def fixdir(dir):
                for v in all_modifs[k]:
                        modif(os.path.join(dir, 'wafadmin'), k, v)
        #print('substitutions finished')
-
diff --git a/wscript b/wscript
index 97c52c3e3eda948baa7391ce09c7c1373a65824d..bbe0cb1105803d73d0f6a8518cfc69752a890ece 100644 (file)
--- a/wscript
+++ b/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'talloc'
-VERSION = '2.1.2'
+VERSION = '2.1.3'
 
 
 blddir = 'bin'
@@ -20,7 +20,8 @@ sys.path.insert(0, srcdir+"/buildtools/wafsamba")
 import wafsamba, samba_dist, Options
 
 # setup what directories to put in a tarball
-samba_dist.DIST_DIRS('lib/talloc:. lib/replace:lib/replace buildtools:buildtools')
+samba_dist.DIST_DIRS("""lib/talloc:. lib/replace:lib/replace
+buildtools:buildtools third_party/waf:third_party/waf""")
 
 
 def set_options(opt):
@@ -59,9 +60,7 @@ def configure(conf):
 
     if not conf.env.disable_python:
         # also disable if we don't have the python libs installed
-        conf.find_program('python', var='PYTHON')
-        conf.check_tool('python')
-        conf.check_python_version((2,4,2))
+        conf.SAMBA_CHECK_PYTHON(mandatory=False, version=(2,4,2))
         conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=False)
         if not conf.env.HAVE_PYTHON_H:
             Logs.warn('Disabling pytalloc-util as python devel libs not found')
@@ -89,9 +88,13 @@ def build(bld):
                           public_headers=[],
                           enabled=bld.env.TALLOC_COMPAT1)
 
+        testsuite_deps = 'talloc'
+        if bld.CONFIG_SET('HAVE_PTHREAD'):
+            testsuite_deps += ' pthread'
+
         bld.SAMBA_BINARY('talloc_testsuite',
                          'testsuite_main.c testsuite.c',
-                         deps='talloc',
+                         testsuite_deps,
                          install=False)
 
     else:
@@ -113,23 +116,34 @@ def build(bld):
                           manpages='man/talloc.3')
 
     if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL') and not bld.env.disable_python:
-        bld.SAMBA_LIBRARY('pytalloc-util',
-            source='pytalloc_util.c',
-            public_deps='talloc',
-            pyembed=True,
-            vnum=VERSION,
-            hide_symbols=True,
-            abi_directory='ABI',
-            abi_match='pytalloc_*',
-            private_library=private_library,
-            public_headers='pytalloc.h',
-            pc_files='pytalloc-util.pc'
-            )
-        bld.SAMBA_PYTHON('pytalloc',
-                         'pytalloc.c',
-                         deps='talloc pytalloc-util',
-                         enabled=True,
-                         realname='talloc.so')
+        for env in bld.gen_python_environments(['PKGCONFIGDIR']):
+            name = bld.pyembed_libname('pytalloc-util')
+
+            bld.SAMBA_LIBRARY(name,
+                source='pytalloc_util.c',
+                public_deps='talloc',
+                pyembed=True,
+                vnum=VERSION,
+                hide_symbols=True,
+                abi_directory='ABI',
+                abi_match='pytalloc_*',
+                private_library=private_library,
+                public_headers='pytalloc.h',
+                pc_files='pytalloc-util.pc'
+                )
+            bld.SAMBA_PYTHON('pytalloc',
+                            'pytalloc.c',
+                            deps='talloc ' + name,
+                            enabled=True,
+                            realname='talloc.so')
+
+            bld.SAMBA_PYTHON('test_pytalloc',
+                            'test_pytalloc.c',
+                            deps='pytalloc',
+                            enabled=True,
+                            realname='_test_pytalloc.so',
+                            install=False)
+
 
 def test(ctx):
     '''run talloc testsuite'''
@@ -137,7 +151,9 @@ def test(ctx):
     cmd = os.path.join(Utils.g_module.blddir, 'talloc_testsuite')
     ret = samba_utils.RUN_COMMAND(cmd)
     print("testsuite returned %d" % ret)
-    sys.exit(ret)
+    pyret = samba_utils.RUN_PYTHON_TESTS(['test_pytalloc.py'])
+    print("python testsuite returned %d" % pyret)
+    sys.exit(ret or pyret)
 
 def dist():
     '''makes a tarball for distribution'''