check-coverage-run recheck-coverage-run: all
$(MKDIR_P) $(PERL_COVERAGE_DB)
PERL5OPT="$$PERL5OPT $(PERL_COVERAGE_FLAGS)"; export PERL5OPT; \
- WANT_NO_THREADS=yes; export WANT_NO_THREADS; unset AUTOMAKE_JOBS; \
$(MAKE) `echo $@ | sed 's/-coverage-run//'`
check-coverage-report:
$(target), $(host) and $(build), have been removed. Simply use this
latter variables.
+* Threaded automake execution (as triggered by $AUTOMAKE_JOBS) has been
+ removed altogether. Exporting AUTOMAKE_JOBS to in the environment of
+ Automake will now have no effect.
+
Source Files with Unknown Extensions
====================================
# Some globals.
-# We do not operate in threaded mode.
-$perl_threads = 0;
-
# Include paths for searching macros. We search macros in this order:
# user-supplied directories first, then the directory containing the
# automake macros, and finally the system-wide directories for
use strict;
use Automake::Config;
-BEGIN
-{
- if ($perl_threads)
- {
- require threads;
- import threads;
- require Thread::Queue;
- import Thread::Queue;
- }
-}
use Automake::General;
use Automake::XFile;
use Automake::Channels;
# when it's defined by Automake. We use INTERNAL in this case.
use constant INTERNAL => new Automake::Location;
-# Serialization keys for message queues.
-use constant QUEUE_MESSAGE => "msg";
-use constant QUEUE_CONF_FILE => "conf file";
-use constant QUEUE_LOCATION => "location";
-use constant QUEUE_STRING => "string";
## ---------------------------------- ##
## Variables related to the options. ##
'install-man' => 1,
);
-# Queue to push require_conf_file requirements to.
-my $required_conf_file_queue;
-
# The name of the Makefile currently being processed.
my $am_file = 'BUG';
}
-# &require_file_internal ($WHERE, $MYSTRICT, $DIRECTORY, $QUEUE, @FILES)
-# ----------------------------------------------------------------------
+# &require_file_internal ($WHERE, $MYSTRICT, $DIRECTORY, @FILES)
+# --------------------------------------------------------------
# Verify that the file must exist in $DIRECTORY, or install it.
# $MYSTRICT is the strictness level at which this file becomes required.
-# Worker threads may queue up the action to be serialized by the master,
-# if $QUEUE is true
sub require_file_internal ($$$@)
{
- my ($where, $mystrict, $dir, $queue, @files) = @_;
+ my ($where, $mystrict, $dir, @files) = @_;
return
unless $strictness >= $mystrict;
foreach my $file (@files)
{
push_required_file ($dir, $file, "$dir/$file");
- if ($queue)
- {
- queue_required_file_check_or_copy ($required_conf_file_queue,
- QUEUE_CONF_FILE, $relative_dir,
- $where, $mystrict, @files);
- }
- else
- {
- required_file_check_or_copy ($where, $dir, $file);
- }
+ required_file_check_or_copy ($where, $dir, $file);
}
}
sub require_file ($$@)
{
my ($where, $mystrict, @files) = @_;
- require_file_internal ($where, $mystrict, $relative_dir, 0, @files);
+ require_file_internal ($where, $mystrict, $relative_dir, @files);
}
# &require_file_with_macro ($COND, $MACRO, $MYSTRICT, @FILES)
if ($config_libobj_dir)
{
require_file_internal ($macro->rdef ($cond)->location, $mystrict,
- $config_libobj_dir, 0, @files);
+ $config_libobj_dir, @files);
}
else
{
}
}
-# &queue_required_file_check_or_copy ($QUEUE, $KEY, $DIR, $WHERE,
-# $MYSTRICT, @FILES)
-# ---------------------------------------------------------------
-sub queue_required_file_check_or_copy ($$$$@)
-{
- my ($queue, $key, $dir, $where, $mystrict, @files) = @_;
- my @serial_loc;
- if (ref $where)
- {
- @serial_loc = (QUEUE_LOCATION, $where->serialize ());
- }
- else
- {
- @serial_loc = (QUEUE_STRING, $where);
- }
- $queue->enqueue ($key, $dir, @serial_loc, $mystrict, 0 + @files, @files);
-}
-
-# &require_queued_file_check_or_copy ($QUEUE)
-# -------------------------------------------
-sub require_queued_file_check_or_copy ($)
-{
- my ($queue) = @_;
- my $where;
- my $dir = $queue->dequeue ();
- my $loc_key = $queue->dequeue ();
- if ($loc_key eq QUEUE_LOCATION)
- {
- $where = Automake::Location::deserialize ($queue);
- }
- elsif ($loc_key eq QUEUE_STRING)
- {
- $where = $queue->dequeue ();
- }
- else
- {
- prog_error "unexpected key $loc_key";
- }
- my $mystrict = $queue->dequeue ();
- my $nfiles = $queue->dequeue ();
- my @files;
- push @files, $queue->dequeue ()
- foreach (1 .. $nfiles);
- return
- unless $strictness >= $mystrict;
- foreach my $file (@files)
- {
- required_file_check_or_copy ($where, $config_aux_dir, $file);
- }
-}
-
# &require_conf_file ($WHERE, $MYSTRICT, @FILES)
# ----------------------------------------------
# Looks in configuration path, as specified by AC_CONFIG_AUX_DIR.
sub require_conf_file ($$@)
{
my ($where, $mystrict, @files) = @_;
- my $queue = defined $required_conf_file_queue ? 1 : 0;
- require_file_internal ($where, $mystrict, $config_aux_dir,
- $queue, @files);
+ require_file_internal ($where, $mystrict, $config_aux_dir, @files);
}
}
}
-# handle_makefiles_serial ()
-# --------------------------
-# Deal with all makefiles, without threads.
-sub handle_makefiles_serial ()
-{
- foreach my $file (@input_files)
- {
- handle_makefile ($file);
- }
-}
-
-# get_number_of_threads ()
-# ------------------------
-# Logic for deciding how many worker threads to use.
-sub get_number_of_threads
-{
- my $nthreads = $ENV{'AUTOMAKE_JOBS'} || 0;
-
- $nthreads = 0
- unless $nthreads =~ /^[0-9]+$/;
-
- # It doesn't make sense to use more threads than makefiles,
- my $max_threads = @input_files;
-
- if ($nthreads > $max_threads)
- {
- $nthreads = $max_threads;
- }
- return $nthreads;
-}
-
-# handle_makefiles_threaded ($NTHREADS)
-# -------------------------------------
-# Deal with all makefiles, using threads. The general strategy is to
-# spawn NTHREADS worker threads, dispatch makefiles to them, and let the
-# worker threads push back everything that needs serialization:
-# * warning and (normal) error messages, for stable stderr output
-# order and content (avoiding duplicates, for example),
-# * races when installing aux files (and respective messages),
-# * races when collecting aux files for distribution.
-#
-# The latter requires that the makefile that deals with the aux dir
-# files be handled last, done by the master thread.
-sub handle_makefiles_threaded ($)
-{
- my ($nthreads) = @_;
-
- # The file queue distributes all makefiles, the message queues
- # collect all serializations needed for respective files.
- my $file_queue = Thread::Queue->new;
- my %msg_queues;
- foreach my $file (@input_files)
- {
- $msg_queues{$file} = Thread::Queue->new;
- }
-
- verb "spawning $nthreads worker threads";
- my @threads = (1 .. $nthreads);
- foreach my $t (@threads)
- {
- $t = threads->new (sub
- {
- while (my $file = $file_queue->dequeue)
- {
- verb "handling $file";
- my $queue = $msg_queues{$file};
- setup_channel_queue ($queue, QUEUE_MESSAGE);
- $required_conf_file_queue = $queue;
- handle_makefile ($file);
- $queue->enqueue (undef);
- setup_channel_queue (undef, undef);
- $required_conf_file_queue = undef;
- }
- return $exit_code;
- });
- }
-
- # Queue all makefiles.
- verb "queuing " . @input_files . " input files";
- $file_queue->enqueue (@input_files, (undef) x @threads);
-
- # Collect and process serializations.
- foreach my $file (@input_files)
- {
- verb "dequeuing messages for " . $file;
- reset_local_duplicates ();
- my $queue = $msg_queues{$file};
- while (my $key = $queue->dequeue)
- {
- if ($key eq QUEUE_MESSAGE)
- {
- pop_channel_queue ($queue);
- }
- elsif ($key eq QUEUE_CONF_FILE)
- {
- require_queued_file_check_or_copy ($queue);
- }
- else
- {
- prog_error "unexpected key $key";
- }
- }
- }
-
- foreach my $t (@threads)
- {
- my @exit_thread = $t->join;
- $exit_code = $exit_thread[0]
- if ($exit_thread[0] > $exit_code);
- }
-}
-
################################################################
# Parse the WARNINGS environment variable.
fatal ("no 'Makefile.am' found for any configure output$msg");
}
-my $nthreads = get_number_of_threads ();
-
-if ($perl_threads && $nthreads >= 1)
- {
- handle_makefiles_threaded ($nthreads);
- }
-else
+foreach my $file (@input_files)
{
- handle_makefiles_serial ();
+ handle_makefile ($file);
}
exit $exit_code;
VERSION=`sed -ne '/AC_INIT/s/^[^[]*\[[^[]*\[\([^]]*\)\].*$/\1/p' configure.ac`
PACKAGE=automake
datadir=.
-PERL_THREADS=0
# This should be automatically updated by the 'update-copyright'
# rule of our Makefile.
RELEASE_YEAR=2012
sed -e "s%@APIVERSION@%$APIVERSION%g" \
-e "s%@PACKAGE@%$PACKAGE%g" \
-e "s%@PERL@%$PERL%g" \
- -e "s%@PERL_THREADS@%$PERL_THREADS%g" \
-e "s%@SHELL@%$BOOTSTRAP_SHELL%g" \
-e "s%@VERSION@%$VERSION%g" \
-e "s%@datadir@%$datadir%g" \
./configure PERL=/path/to/perl])
}
-# We require ithreads support, and version 5.7.2 for CLONE.
-AC_CACHE_CHECK([whether $PERL supports ithreads], [am_cv_prog_PERL_ithreads],
-[if $PERL -e '
- require 5.007_002;
- use Config;
- if ($Config{useithreads})
- {
- require threads;
- import threads;
- require Thread::Queue;
- import Thread::Queue;
- exit 0;
- }
- exit 1;' >&AS_MESSAGE_LOG_FD 2>&1
-then
- am_cv_prog_PERL_ithreads=yes
-else
- am_cv_prog_PERL_ithreads=no
-fi])
-if test $am_cv_prog_PERL_ithreads = yes; then
- PERL_THREADS=1;
-else
- PERL_THREADS=0;
-fi
-AC_SUBST([PERL_THREADS])
-
# The test suite will skip some tests if tex is absent.
AC_CHECK_PROG([TEX], [tex], [tex])
# Save details about the selected TeX program in config.log.
@end table
-@vindex AUTOMAKE_JOBS
-If the environment variable @env{AUTOMAKE_JOBS} contains a positive
-number, it is taken as the maximum number of Perl threads to use in
-@command{automake} for generating multiple @file{Makefile.in} files
-concurrently. This is an experimental feature.
-
@node configure
@chapter Scanning @file{configure.ac}, using @command{aclocal}
package Automake::ChannelDefs;
use Automake::Config;
-BEGIN
-{
- if ($perl_threads)
- {
- require threads;
- import threads;
- }
-}
use Automake::Channels;
=head1 NAME
# Do not forget to update &usage and the manual
# if you add or change a warning channel.
-register_channel 'fatal', type => 'fatal', uniq_part => UP_NONE, ordered => 0;
+register_channel 'fatal', type => 'fatal', uniq_part => UP_NONE;
register_channel 'error', type => 'error';
register_channel 'error-gnu', type => 'error';
register_channel 'error-gnu/warn', type => 'error';
"## Internal Error ##\n" .
"####################\n"),
footer => "\nPlease contact <$PACKAGE_BUGREPORT>.",
- uniq_part => UP_NONE, ordered => 0;
+ uniq_part => UP_NONE;
register_channel 'extra-portability', type => 'warning', silent => 1;
register_channel 'gnu', type => 'warning';
register_channel 'syntax', type => 'warning';
register_channel 'unsupported', type => 'warning';
-register_channel 'verb', type => 'debug', silent => 1, uniq_part => UP_NONE,
- ordered => 0;
+register_channel 'verb', type => 'debug', silent => 1, uniq_part => UP_NONE;
register_channel 'note', type => 'debug', silent => 0;
setup_channel_type 'warning', header => 'warning: ';
sub verb ($;%)
{
my ($msg, %opts) = @_;
- $msg = "thread " . threads->tid . ": " . $msg
- if $perl_threads;
msg 'verb', '', $msg, %opts;
}
# Turn on all channels of type 'warning'.
setup_channel_type 'warning', silent => 0;
- # Redirect all channels to push messages on a Thread::Queue using
- # the specified serialization key.
- setup_channel_queue $queue, $key;
-
- # Output a message pending in a Thread::Queue.
- pop_channel_queue $queue;
-
# Treat all warnings as errors.
$warnings_are_errors = 1;
&setup_channel &setup_channel_type
&dup_channel_setup &drop_channel_setup
&buffer_messages &flush_messages
- &setup_channel_queue &pop_channel_queue
US_GLOBAL US_LOCAL
UP_NONE UP_TEXT UP_LOC_TEXT);
Whether the channel should be silent. Use this do disable a
category of warning, for instance.
-=item C<ordered =E<gt> 1>
-
-Whether, with multi-threaded execution, the message should be queued
-for ordered output.
-
=item C<uniq_part =E<gt> UP_LOC_TEXT>
The part of the message subject to duplicate filtering. See the
exit_code => 1,
file => \*STDERR,
silent => 0,
- ordered => 1,
- queue => 0,
- queue_key => undef,
uniq_scope => US_LOCAL,
uniq_part => UP_LOC_TEXT,
header => '',
confess "unknown option '$_'";
}
}
- if ($hash->{'ordered'})
- {
- confess "fatal messages cannot be ordered"
- if $hash->{'type'} eq 'fatal';
- confess "backtrace cannot be output on ordered messages"
- if $hash->{'backtrace'};
- }
}
=item C<register_channel ($name, [%options])>
return $msg;
}
-# _enqueue ($QUEUE, $KEY, $UNIQ_SCOPE, $TO_FILTER, $MSG, $FILE)
-# -------------------------------------------------------------
-# Push message on a queue, to be processed by another thread.
-sub _enqueue ($$$$$$)
-{
- my ($queue, $key, $uniq_scope, $to_filter, $msg, $file) = @_;
- $queue->enqueue ($key, $msg, $to_filter, $uniq_scope);
- confess "message queuing works only for STDERR"
- if $file ne \*STDERR;
-}
-
-# _dequeue ($QUEUE)
-# -----------------
-# Pop a message from a queue, and print, similarly to how
-# _print_message would do it. Return 0 if the queue is
-# empty. Note that the key has already been dequeued.
-sub _dequeue ($)
-{
- my ($queue) = @_;
- my $msg = $queue->dequeue || return 0;
- my $to_filter = $queue->dequeue;
- my $uniq_scope = $queue->dequeue;
- my $file = \*STDERR;
-
- if ($to_filter ne '')
- {
- # Do we want local or global uniqueness?
- my $dups;
- if ($uniq_scope == US_LOCAL)
- {
- $dups = \%_local_duplicate_messages;
- }
- elsif ($uniq_scope == US_GLOBAL)
- {
- $dups = \%_global_duplicate_messages;
- }
- else
- {
- confess "unknown value for uniq_scope: " . $uniq_scope;
- }
-
- # Update the hash of messages.
- if (exists $dups->{$to_filter})
- {
- ++$dups->{$to_filter};
- return 1;
- }
- else
- {
- $dups->{$to_filter} = 0;
- }
- }
- print $file $msg;
- return 1;
-}
-
-
# _print_message ($LOCATION, $MESSAGE, %OPTIONS)
# ----------------------------------------------
# Format the message, check duplicates, and print it.
}
}
my $file = $opts{'file'};
- if ($opts{'ordered'} && $opts{'queue'})
- {
- _enqueue ($opts{'queue'}, $opts{'queue_key'}, $opts{'uniq_scope'},
- $to_filter, $msg, $file);
- }
- else
- {
- print $file $msg;
- }
+ print $file $msg;
return 1;
}
confess if $opts{'backtrace'};
if ($opts{'type'} eq 'fatal')
{
- # flush messages explicitly here, needed in worker threads.
+ # Flush messages explicitly here, for extra safety.
STDERR->flush;
exit $exit_code;
}
@backlog = ();
}
-=item C<setup_channel_queue ($queue, $key)>
-
-Set the queue to fill for each channel that is ordered,
-and the key to use for serialization.
-
-=cut
-sub setup_channel_queue ($$)
-{
- my ($queue, $key) = @_;
- foreach my $channel (keys %channels)
- {
- setup_channel $channel, queue => $queue, queue_key => $key
- if $channels{$channel}{'ordered'};
- }
-}
-
-=item C<pop_channel_queue ($queue)>
-
-pop a message off the $queue; the key has already been popped.
-
-=cut
-sub pop_channel_queue ($)
-{
- my ($queue) = @_;
- return _dequeue ($queue);
-}
-
=back
=head1 SEE ALSO
our @ISA = qw (Exporter);
our @EXPORT = qw ($APIVERSION $PACKAGE $PACKAGE_BUGREPORT $VERSION
- $RELEASE_YEAR $libdir $perl_threads);
+ $RELEASE_YEAR $libdir);
# Parameters set by configure. Not to be changed. NOTE: assign
# VERSION as string so that e.g. version 0.30 will print correctly.
our $VERSION = '@VERSION@';
our $RELEASE_YEAR = '@RELEASE_YEAR@';
our $libdir = '@datadir@/@PACKAGE@-@APIVERSION@';
-our $perl_threads = @PERL_THREADS@;
1;
return $self;
}
-
-=item C<CLONE>
-
-Internal special subroutine to fix up the self hashes in
-C<%_disjcondition_singletons> upon thread creation. C<CLONE> is invoked
-automatically with ithreads from Perl 5.7.2 or later, so if you use this
-module with earlier versions of Perl, it is not thread-safe.
-
-=cut
-
-sub CLONE
-{
- foreach my $self (values %_disjcondition_singletons)
- {
- my %h = map { $_ => $_ } @{$self->{'conds'}};
- $self->{'hash'} = \%h;
- }
-}
-
-
=item C<@conds = $set-E<gt>conds>
Return the list of C<Condition> objects involved in C<$set>.
# that would otherwise be modified.
my $where_copy = $where->clone;
- # Serialize a Location object (for passing through a thread queue,
- # for example)
- my @array = $where->serialize ();
-
- # De-serialize: recreate a Location object from a queue.
- my $where = new Automake::Location::deserialize ($queue);
-
=head1 DESCRIPTION
C<Location> objects are used to keep track of locations in Automake,
return $res;
}
-=item C<@array = $location-E<gt>serialize>
-
-Serialize a Location object (for passing through a thread queue,
-for example).
-
-=cut
-
-sub serialize ($)
-{
- my ($self) = @_;
- my @serial = ();
- push @serial, $self->get;
- my @contexts = $self->get_contexts;
- for my $pair (@contexts)
- {
- push @serial, @{$pair};
- }
- push @serial, undef;
- return @serial;
-}
-
-=item C<new Automake::Location::deserialize ($queue)>
-
-De-serialize: recreate a Location object from a queue.
-
-=cut
-
-sub deserialize ($)
-{
- my ($queue) = @_;
- my $position = $queue->dequeue ();
- my $self = new Automake::Location $position;
- while (my $position = $queue->dequeue ())
- {
- my $context = $queue->dequeue ();
- push @{$self->{'contexts'}}, [$position, $context];
- }
- return $self;
-}
-
=back
=head1 SEE ALSO
fi
unset priv_check_temp overwrite_status
;;
- # Extra quoting required to avoid maintainer-check spurious failures.
- 'perl-threads')
- if test "$WANT_NO_THREADS" = "yes"; then
- skip_all_ "Devel::Cover cannot cope with threads"
- fi
- ;;
native)
# Don't use "&&" here, to avoid a bug of 'set -e' present in
# some (even relatively recent) versions of the BSD shell.
+++ /dev/null
-#! /bin/sh
-# Copyright (C) 2008-2012 Free Software Foundation, Inc.
-#
-# 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 2, 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/>.
-
-# Test parallel automake execution.
-
-# There are several hypotheses to be tested: Independently of the number
-# of threads used by automake,
-# 0) the generated Makefile.in files must be identical without --add-missing,
-# 1) the Makefile.in that distributes auxiliary files must be generated
-# after all other ones, so all installed aux files are caught,
-# 2) normal automake output should have identical content and be ordered
-# in the same way, when --add-missing is not passed, or when
-# --add-missing is passed but there are no concurrent file requirements
-# (i.e., two Makefile.am files call for the same needed aux file)
-# 3) normal automake output should be identical and ordered in the same way
-# with --add-missing, even with concurrent file requirements, and the
-# installation of aux files should be race-free,
-# 4) warning and normal error output should be identical, in that duplicate
-# warnings should be omitted in the same way as without threads,
-# 5) fatal error and debug messages could be identical. This is not
-# intended, though.
-#
-# This test checks (0), (1), and (2). See sister tests for further coverage.
-
-required=perl-threads
-. ./defs || exit 1
-
-cat > configure.ac << 'END'
-AC_INIT([parallel-am], [1.0])
-AC_CONFIG_AUX_DIR([build-aux])
-AM_INIT_AUTOMAKE
-AC_PROG_CC
-AM_PATH_LISPDIR
-AM_PATH_PYTHON
-AC_CONFIG_FILES([Makefile])
-END
-
-cat > Makefile.am << 'END'
-SUBDIRS =
-END
-
-list='1 2 3 4 5 6 7 8 9'
-for i in $list; do
- echo "AC_CONFIG_FILES([sub$i/Makefile])" >> configure.ac
- echo "SUBDIRS += sub$i" >> Makefile.am
- mkdir sub$i
- echo > sub$i/Makefile.am
-done
-# Use an include chain to cause a nontrivial location object to be
-# serialized through a thread queue.
-echo 'include foo.am' >> sub7/Makefile.am
-echo 'include bar.am' > sub7/foo.am
-echo 'python_PYTHON = foo.py' > sub7/bar.am
-echo 'lisp_LISP = foo.el' >> sub8/Makefile.am
-echo 'bin_PROGRAMS = p' >> sub9/Makefile.am
-
-rm -f install-sh missing depcomp
-mkdir build-aux
-
-$ACLOCAL
-
-# This test may have to be run several times in order to expose the
-# race that, when the last Makefile.in (the toplevel one) is created
-# before the other ones have finished, not all auxiliary files may
-# be installed yet, thus some may not be distributed.
-#
-# Further, automake output should be stable.
-
-# Generate expected output using the non-threaded code.
-unset AUTOMAKE_JOBS || :
-AUTOMAKE_run --add-missing
-mv stderr expected
-Makefile_ins=$(find . -name Makefile.in)
-for file in $Makefile_ins; do
- mv $file $file.exp
-done
-
-AUTOMAKE_JOBS=5
-export AUTOMAKE_JOBS
-
-for run in 1 2 3 4 5 6 7; do
- rm -f build-aux/* sub*/Makefile.in
- AUTOMAKE_run --add-missing
- diff stderr expected
- for file in $Makefile_ins; do
- diff $file $file.exp
- done
-done
-
-:
+++ /dev/null
-#! /bin/sh
-# Copyright (C) 2008-2012 Free Software Foundation, Inc.
-#
-# 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 2, 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/>.
-
-# Test parallel automake execution.
-
-# This tests:
-# 4) warning and normal error output should be identical, in that duplicate
-# warnings should be omitted in the same way as without threads.
-
-required=perl-threads
-. ./defs || exit 1
-
-mkdir sub
-
-cat > Makefile.am << 'END'
-bin_PROGRAMS = main
-main_SOURCES = sub/main.c
-SUBDIRS =
-END
-
-list='1 2 3'
-for i in $list; do
- echo "AC_CONFIG_FILES([sub$i/Makefile])" >> configure.ac
- echo "SUBDIRS += sub$i" >> Makefile.am
- mkdir sub$i sub$i/sub
- unindent > sub$i/Makefile.am << END
- bin_PROGRAMS = sub$i
- sub${i}_SOURCES = sub/main$i.c
-END
-done
-
-mkdir build-aux
-
-$ACLOCAL
-
-# Independently of the number of worker threads, automake output
-# should be
-# - stable (multiple runs should produce the same output),
-# - properly uniquified,
-# - complete (output from worker threads should not be lost).
-#
-# The parts output by --add-missing are unstable not only wrt. order
-# but also wrt. content: any of the Makefile.am files may cause the
-# depcomp script to be installed (or several of them).
-# Thus we install the auxiliary files in a prior step.
-
-# Generate expected output using non-threaded code.
-unset AUTOMAKE_JOBS || :
-rm -f install-sh missing depcomp
-AUTOMAKE_fails --add-missing
-mv stderr expected
-
-AUTOMAKE_JOBS=5
-export AUTOMAKE_JOBS
-
-for i in 1 2 3 4 5 6 7 8; do
- rm -f install-sh missing depcomp
- AUTOMAKE_fails --add-missing
- diff expected stderr
-done
-
-:
+++ /dev/null
-#! /bin/sh
-# Copyright (C) 2008-2012 Free Software Foundation, Inc.
-#
-# 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 2, 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/>.
-
-# Test parallel automake execution.
-
-# This tests:
-# 3) normal automake output should be identical and ordered in the same way
-# with --add-missing, even with concurrent file requirements, and the
-# installation of aux files should be race-free.
-
-required=perl-threads
-. ./defs || exit 1
-
-cat > configure.ac << 'END'
-AC_INIT([parallel-am], [1.0])
-AC_CONFIG_AUX_DIR([build-aux])
-AM_INIT_AUTOMAKE
-AC_PROG_CC
-AM_PATH_LISPDIR
-AM_PATH_PYTHON
-AC_CONFIG_FILES([Makefile])
-END
-
-cat > Makefile.am << 'END'
-SUBDIRS =
-END
-
-list='1 2 3'
-for i in $list; do
- echo "AC_CONFIG_FILES([sub$i/Makefile])" >> configure.ac
- echo "SUBDIRS += sub$i" >> Makefile.am
- mkdir sub$i
- unindent > sub$i/Makefile.am <<END
- python_PYTHON = foo$i.py
- lisp_LISP = foo$i.el
- bin_PROGRAMS = p$i
-END
-done
-
-rm -f install-sh missing depcomp
-mkdir build-aux
-
-$ACLOCAL
-
-# Generate expected output using the non-threaded code.
-unset AUTOMAKE_JOBS || :
-AUTOMAKE_run --add-missing
-mv stderr expected
-mv Makefile.in Makefile.in.exp
-
-AUTOMAKE_JOBS=3
-export AUTOMAKE_JOBS
-
-for run in 1 2 3 4 5 6 7; do
- rm -f build-aux/* sub*/Makefile.in
- AUTOMAKE_run --add-missing
- diff stderr expected
- diff Makefile.in Makefile.in.exp
-done
-
-:
+++ /dev/null
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
-#
-# 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 2, 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/>.
-
-BEGIN {
- use Config;
- if (eval { require 5.007_002; } # for CLONE support
- && $Config{useithreads}
- && !$ENV{WANT_NO_THREADS})
- {
- require threads;
- import threads;
- }
- else
- {
- exit 77;
- }
-}
-use Automake::Condition qw/TRUE FALSE/;
-
-sub test_basics ()
-{
- my @tests = (# [[Conditions], is_true?, is_false?, string, subst-string, human]
- [[], 1, 0, 'TRUE', '', 'TRUE'],
- [['TRUE'], 1, 0, 'TRUE', '', 'TRUE'],
- [['FALSE'], 0, 1, 'FALSE', '#', 'FALSE'],
- [['A_TRUE'], 0, 0, 'A_TRUE', '@A_TRUE@', 'A'],
- [['A_TRUE', 'B_FALSE'],
- 0, 0, 'A_TRUE B_FALSE', '@A_TRUE@@B_FALSE@', 'A and !B'],
- [['B_TRUE', 'FALSE'], 0, 1, 'FALSE', '#', 'FALSE'],
- [['B_TRUE', 'B_FALSE'], 0, 1, 'FALSE', '#', 'FALSE']);
-
- for (@tests)
- {
- my $a = new Automake::Condition @{$_->[0]};
- return 1
- if threads->new(sub {
- return 1 if $_->[1] != $a->true;
- return 1 if $_->[1] != ($a == TRUE);
- return 1 if $_->[2] != $a->false;
- return 1 if $_->[2] != ($a == FALSE);
- return 1 if $_->[3] ne $a->string;
- return 1 if $_->[4] ne $a->subst_string;
- return 1 if $_->[5] ne $a->human;
- })->join;
- }
- return 0;
-}
-
-sub test_true_when ()
-{
- my $failed = 0;
-
- my @tests = (# [When,
- # [Implied-Conditions],
- # [Not-Implied-Conditions]]
- [['TRUE'],
- [['TRUE']],
- [['A_TRUE'], ['A_TRUE', 'B_FALSE'], ['FALSE']]],
- [['A_TRUE'],
- [['TRUE'], ['A_TRUE']],
- [['A_TRUE', 'B_FALSE'], ['FALSE']]],
- [['A_TRUE', 'B_FALSE'],
- [['TRUE'], ['A_TRUE'], ['B_FALSE'], ['A_TRUE', 'B_FALSE']],
- [['FALSE'], ['C_FALSE'], ['C_FALSE', 'A_TRUE']]]);
-
- for my $t (@tests)
- {
- my $a = new Automake::Condition @{$t->[0]};
- return 1
- if threads->new(sub {
- for my $u (@{$t->[1]})
- {
- my $b = new Automake::Condition @$u;
- return threads->new(sub {
- if (! $b->true_when ($a))
- {
- print "`" . $b->string .
- "' not implied by `" . $a->string . "'?\n";
- $failed = 1;
- }
- })->join;
- }
- for my $u (@{$t->[2]})
- {
- my $b = new Automake::Condition @$u;
- return threads->new(sub {
- if ($b->true_when ($a))
- {
- print "`" . $b->string .
- "' implied by `" . $a->string . "'?\n";
- $failed = 1;
- }
-
- return threads->new(sub {
- return 1 if $b->true_when ($a);
- })->join;
- })->join;
- }
- })->join;
- }
- return $failed;
-}
-
-sub test_reduce_and ()
-{
- my @tests = (# If no conditions are given, TRUE should be returned
- [[], ["TRUE"]],
- # An empty condition is TRUE
- [[""], ["TRUE"]],
- # A single condition should be passed through unchanged
- [["FOO"], ["FOO"]],
- [["FALSE"], ["FALSE"]],
- [["TRUE"], ["TRUE"]],
- # TRUE and false should be discarded and overwhelm
- # the result, respectively
- [["FOO", "TRUE"], ["FOO"]],
- [["FOO", "FALSE"], ["FALSE"]],
- # Repetitions should be removed
- [["FOO", "FOO"], ["FOO"]],
- [["TRUE", "FOO", "FOO"], ["FOO"]],
- [["FOO", "TRUE", "FOO"], ["FOO"]],
- [["FOO", "FOO", "TRUE"], ["FOO"]],
- # Two different conditions should be preserved,
- # but TRUEs should be removed
- [["FOO", "BAR"], ["BAR,FOO"]],
- [["TRUE", "FOO", "BAR"], ["BAR,FOO"]],
- [["FOO", "TRUE", "BAR"], ["BAR,FOO"]],
- [["FOO", "BAR", "TRUE"], ["BAR,FOO"]],
- # A condition implied by another condition should be removed.
- [["FOO BAR", "BAR"], ["FOO BAR"]],
- [["BAR", "FOO BAR"], ["FOO BAR"]],
- [["TRUE", "FOO BAR", "BAR"], ["FOO BAR"]],
- [["FOO BAR", "TRUE", "BAR"], ["FOO BAR"]],
- [["FOO BAR", "BAR", "TRUE"], ["FOO BAR"]],
-
- [["BAR FOO", "BAR"], ["BAR FOO"]],
- [["BAR", "BAR FOO"], ["BAR FOO"]],
- [["TRUE", "BAR FOO", "BAR"], ["BAR FOO"]],
- [["BAR FOO", "TRUE", "BAR"], ["BAR FOO"]],
- [["BAR FOO", "BAR", "TRUE"], ["BAR FOO"]],
-
- # Check that reduction happens even when there are
- # two conditions to remove.
- [["FOO", "FOO BAR", "BAR"], ["FOO BAR"]],
- [["FOO", "FOO BAR", "BAZ", "FOO BAZ"], ["FOO BAR", "FOO BAZ"]],
- [["FOO", "FOO BAR", "BAZ", "FOO BAZ", "FOO BAZ BAR"],
- ["FOO BAZ BAR"]],
-
- # Duplicated conditionals should be removed.
- [["FOO", "BAR", "BAR"], ["BAR,FOO"]],
-
- # Equivalent conditions in different forms should be
- # reduced: which one is left is unfortunately order
- # dependent.
- [["BAR FOO", "FOO BAR"], ["FOO BAR"]],
- [["FOO BAR", "BAR FOO"], ["BAR FOO"]]);
-
- my $failed = 0;
- foreach (@tests)
- {
- my ($inref, $outref) = @$_;
- my @inconds = map { new Automake::Condition $_ } @$inref;
- return 1
- if threads->new(sub {
- my @outconds = map { (new Automake::Condition $_)->string } @$outref;
- return threads->new(sub {
- my @res =
- map { $_->string } (Automake::Condition::reduce_and (@inconds));
- return threads->new(sub {
- my $result = join (",", sort @res);
- my $exresult = join (",", @outconds);
-
- if ($result ne $exresult)
- {
- print '"' . join(",", @$inref) . '" => "' .
- $result . '" expected "' .
- $exresult . '"' . "\n";
- $failed = 1;
- }
- return $failed;
- })->join;
- })->join;
- })->join;
- }
- return $failed;
-}
-
-sub test_reduce_or ()
-{
- my @tests = (# If no conditions are given, FALSE should be returned
- [[], ["FALSE"]],
- # An empty condition is TRUE
- [[""], ["TRUE"]],
- # A single condition should be passed through unchanged
- [["FOO"], ["FOO"]],
- [["FALSE"], ["FALSE"]],
- [["TRUE"], ["TRUE"]],
- # FALSE and TRUE should be discarded and overwhelm
- # the result, respectively
- [["FOO", "TRUE"], ["TRUE"]],
- [["FOO", "FALSE"], ["FOO"]],
- # Repetitions should be removed
- [["FOO", "FOO"], ["FOO"]],
- [["FALSE", "FOO", "FOO"], ["FOO"]],
- [["FOO", "FALSE", "FOO"], ["FOO"]],
- [["FOO", "FOO", "FALSE"], ["FOO"]],
- # Two different conditions should be preserved,
- # but FALSEs should be removed
- [["FOO", "BAR"], ["BAR,FOO"]],
- [["FALSE", "FOO", "BAR"], ["BAR,FOO"]],
- [["FOO", "FALSE", "BAR"], ["BAR,FOO"]],
- [["FOO", "BAR", "FALSE"], ["BAR,FOO"]],
- # A condition implying another condition should be removed.
- [["FOO BAR", "BAR"], ["BAR"]],
- [["BAR", "FOO BAR"], ["BAR"]],
- [["FALSE", "FOO BAR", "BAR"], ["BAR"]],
- [["FOO BAR", "FALSE", "BAR"], ["BAR"]],
- [["FOO BAR", "BAR", "FALSE"], ["BAR"]],
-
- [["BAR FOO", "BAR"], ["BAR"]],
- [["BAR", "BAR FOO"], ["BAR"]],
- [["FALSE", "BAR FOO", "BAR"], ["BAR"]],
- [["BAR FOO", "FALSE", "BAR"], ["BAR"]],
- [["BAR FOO", "BAR", "FALSE"], ["BAR"]],
-
- # Check that reduction happens even when there are
- # two conditions to remove.
- [["FOO", "FOO BAR", "BAR"], ["BAR,FOO"]],
- [["FOO", "FOO BAR", "BAZ", "FOO BAZ"], ["BAZ,FOO"]],
- [["FOO", "FOO BAR", "BAZ", "FOO BAZ", "FOO BAZ BAR"],
- ["BAZ,FOO"]],
-
- # Duplicated conditionals should be removed.
- [["FOO", "BAR", "BAR"], ["BAR,FOO"]],
-
- # Equivalent conditions in different forms should be
- # reduced: which one is left is unfortunately order
- # dependent.
- [["BAR FOO", "FOO BAR"], ["FOO BAR"]],
- [["FOO BAR", "BAR FOO"], ["BAR FOO"]]);
-
- my $failed = 0;
- foreach (@tests)
- {
- my ($inref, $outref) = @$_;
- my @inconds = map { new Automake::Condition $_ } @$inref;
- return 1
- if threads->new(sub {
- my @outconds = map { (new Automake::Condition $_)->string } @$outref;
- return threads->new(sub {
- my @res =
- map { $_->string } (Automake::Condition::reduce_or (@inconds));
- return threads->new(sub {
- my $result = join (",", sort @res);
- my $exresult = join (",", @outconds);
-
- if ($result ne $exresult)
- {
- print '"' . join(",", @$inref) . '" => "' .
- $result . '" expected "' .
- $exresult . '"' . "\n";
- $failed = 1;
- }
- return $failed;
- })->join;
- })->join;
- })->join;
- }
- return $failed;
-}
-
-sub test_merge ()
-{
- my $cond = new Automake::Condition "COND1_TRUE", "COND2_FALSE";
- return threads->new(sub {
- my $other = new Automake::Condition "COND3_FALSE";
- return threads->new(sub {
- my $both = $cond->merge ($other);
- return threads->new(sub {
- my $both2 = $cond->merge_conds ("COND3_FALSE");
- return threads->new(sub {
- $cond = $both->strip ($other);
- my @conds = $cond->conds;
- return 1 if $both->string ne "COND1_TRUE COND2_FALSE COND3_FALSE";
- return 1 if $cond->string ne "COND1_TRUE COND2_FALSE";
- return 1 if $both != $both2;
- })->join;
- })->join;
- })->join;
- })->join;
- return 0;
-}
-
-exit (test_basics
- || test_true_when
- || test_reduce_and
- || test_reduce_or
- || test_merge);
-
-### Setup "GNU" style for perl-mode and cperl-mode.
-## Local Variables:
-## perl-indent-level: 2
-## perl-continued-statement-offset: 2
-## perl-continued-brace-offset: 0
-## perl-brace-offset: 0
-## perl-brace-imaginary-offset: 0
-## perl-label-offset: -2
-## cperl-indent-level: 2
-## cperl-brace-offset: 0
-## cperl-continued-brace-offset: 0
-## cperl-label-offset: -2
-## cperl-extra-newline-before-brace: t
-## cperl-merge-trailing-else: nil
-## cperl-continued-statement-offset: 2
-## End:
+++ /dev/null
-# Copyright (C) 2001-2012 Free Software Foundation, Inc.
-#
-# 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 2, 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/>.
-
-BEGIN {
- use Config;
- if (eval { require 5.007_002; } # for CLONE support
- && $Config{useithreads}
- && !$ENV{WANT_NO_THREADS})
- {
- require threads;
- import threads;
- }
- else
- {
- exit 77;
- }
-}
-use Automake::Condition qw/TRUE FALSE/;
-use Automake::DisjConditions;
-
-sub test_basics ()
-{
- my $true = new Automake::DisjConditions TRUE;
- my $false = new Automake::DisjConditions FALSE;
- my $cond = new Automake::Condition "COND1_TRUE", "COND2_FALSE";
- return threads->new (sub {
- my $other = new Automake::Condition "COND3_FALSE";
- my $another = new Automake::Condition "COND3_TRUE", "COND4_FALSE";
- return threads->new (sub {
- my $set1 = new Automake::DisjConditions $cond, $other;
- return threads->new (sub {
- my $set2 = new Automake::DisjConditions $other, $cond;
- my $set3 = new Automake::DisjConditions FALSE, $another;
- return 1 unless $set1 == $set2;
- return 1 if $set1->false;
- return 1 if $set1->true;
- return 1 unless (new Automake::DisjConditions)->false;
- return 1 if (new Automake::DisjConditions)->true;
- return 1 unless $true->human eq 'TRUE';
- return 1 unless $false->human eq 'FALSE';
- return 1 unless $set1->human eq "(COND1 and !COND2) or (!COND3)";
- return 1 unless $set2->human eq "(COND1 and !COND2) or (!COND3)";
- my $one_cond_human = $set1->one_cond->human;
- return 1 unless $one_cond_human eq "!COND3"
- || $one_cond_human eq "COND1 and !COND2";
- return 1 unless $set1->string eq "COND1_TRUE COND2_FALSE | COND3_FALSE";
-
- my $merged1 = $set1->merge ($set2);
- my $merged2 = $set1->merge ($cond);
- my $mult1 = $set1->multiply ($set3);
- return threads->new (sub {
- my $mult2 = $set1->multiply ($another);
- return threads->new (sub {
- return 1 unless $merged1->simplify->string eq "COND1_TRUE COND2_FALSE | COND3_FALSE";
- return 1 unless $merged2->simplify->string eq "COND1_TRUE COND2_FALSE | COND3_FALSE";
- return 1 unless $mult1->string eq "COND1_TRUE COND2_FALSE COND3_TRUE COND4_FALSE";
- return 1 unless $mult1 == $mult2;
- return 0;
- })->join;
- })->join;
- })->join;
- })->join;
- })->join;
-}
-
-sub build_set (@)
-{
- my @conds = @_;
- my @set = ();
- for my $cond (@conds)
- {
- push @set, new Automake::Condition @$cond;
- }
- return new Automake::DisjConditions @set;
-}
-
-sub test_invert ()
-{
- my @tests = ([[["FALSE"]],
- [["TRUE"]]],
-
- [[["TRUE"]],
- [["FALSE"]]],
-
- [[["COND1_TRUE", "COND2_TRUE"],
- ["COND3_FALSE", "COND2_TRUE"]],
- [["COND2_FALSE"],
- ["COND1_FALSE", "COND3_TRUE"]]],
-
- [[["COND1_TRUE", "COND2_TRUE"],
- ["TRUE"]],
- [["FALSE"]]],
-
- [[["COND1_TRUE", "COND2_TRUE"],
- ["FALSE"]],
- [["COND1_FALSE"],
- ["COND2_FALSE"]]],
-
- [[["COND1_TRUE"],
- ["COND2_FALSE"]],
- [["COND1_FALSE", "COND2_TRUE"]]]
- );
-
- for my $t (@tests)
- {
- my $set = build_set @{$t->[0]};
- return 1
- if threads->new(sub {
- my $res = build_set @{$t->[1]};
- my $inv = $set->invert;
- if ($inv != $res)
- {
- print " (I) " . $set->string . "\n\t"
- . $inv->string . ' != ' . $res->string . "\n";
- return 1;
- }
- return 0
- })-> join;
- }
- return 0;
-}
-
-sub test_simplify ()
-{
- my @tests = ([[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"]],
- [["FOO_TRUE", "BAR_FALSE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["FOO_TRUE", "BAR_TRUE"]],
- [["FOO_TRUE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["FOO_TRUE", "BAR_TRUE"],
- ["FOO_FALSE"]],
- [["TRUE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["BAR_TRUE", "BAZ_TRUE"],
- ["BAR_FALSE", "BAZ_TRUE"]],
- [["BAZ_TRUE"], ["FOO_TRUE", "BAR_FALSE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["BAR_TRUE", "BAZ_TRUE"],
- ["BAR_FALSE", "BAZ_TRUE"],
- ["FOO_FALSE"]],
- [["FOO_FALSE"], ["BAZ_TRUE"], ["BAR_FALSE"]]],
-
- [[["B_TRUE"],
- ["A_FALSE", "B_TRUE"]],
- [["B_TRUE"]]],
-
- [[["B_TRUE"],
- ["A_FALSE", "B_FALSE", "C_TRUE"],
- ["A_FALSE", "B_FALSE", "C_FALSE"]],
- [["A_FALSE"], ["B_TRUE"]]],
-
- [[["B_TRUE"],
- ["A_FALSE", "B_FALSE", "C_TRUE"],
- ["A_FALSE", "B_FALSE", "C_FALSE"],
- ["A_TRUE", "B_FALSE"]],
- [["TRUE"]]],
-
- [[["A_TRUE", "B_TRUE"],
- ["A_TRUE", "B_FALSE"],
- ["A_TRUE", "C_FALSE", "D_FALSE"]],
- [["A_TRUE"]]],
-
- [[["A_FALSE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
- ["A_FALSE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["A_FALSE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["A_FALSE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["A_TRUE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["A_TRUE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"]],
- [ ["B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
- ["B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"]]],
-
- [[["A_FALSE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
- ["A_FALSE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["A_FALSE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["A_FALSE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["A_TRUE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["A_TRUE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
- ["A_FALSE", "B_FALSE", "C_FALSE", "D_FALSE", "E_FALSE"],
- ["A_FALSE", "B_FALSE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["A_FALSE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["A_FALSE", "B_TRUE", "C_FALSE", "D_TRUE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_FALSE", "D_TRUE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"],
- ["A_TRUE", "B_FALSE", "C_TRUE", "D_FALSE", "E_TRUE"],
- ["A_TRUE", "B_FALSE", "C_FALSE", "D_FALSE", "E_FALSE"]],
- [["C_FALSE", "E_FALSE"],
- ["C_TRUE", "E_TRUE"]]],
-
- [[["A_FALSE"],
- ["A_TRUE", "B_FALSE"],
- ["A_TRUE", "B_TRUE", "C_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE", "F_FALSE"],
- ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"]],
- [["TRUE"]]],
-
- # Simplify should work with up to 31 variables.
- [[["V01_TRUE", "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
- "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
- "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
- "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
- "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
- "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
- "V31_TRUE"],
- ["V01_TRUE", "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
- "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
- "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
- "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
- "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
- "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
- "V31_FALSE"],
- ["V01_FALSE","V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
- "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
- "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
- "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
- "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
- "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
- "V31_TRUE"],
- ["V01_FALSE","V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
- "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
- "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
- "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
- "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
- "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
- "V31_FALSE"]],
- [[ "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
- "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
- "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
- "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
- "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
- "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE"
- ]]]);
-
- for my $t (@tests)
- {
- my $set = build_set @{$t->[0]};
- return 1
- if threads->new(sub {
- my $res = build_set @{$t->[1]};
- return threads->new(sub {
-
- # Make sure simplify() yields the expected result.
- my $sim = $set->simplify;
- return threads->new(sub {
- if ($sim != $res)
- {
- print " (S1) " . $set->string . "\n\t"
- . $sim->string . ' != ' . $res->string . "\n";
- return 1;
- }
-
- # Make sure simplify() is idempotent.
- my $sim2 = $sim->simplify;
- return threads->new(sub {
- if ($sim2 != $sim)
- {
- print " (S2) " . $sim->string . "\n\t"
- . $sim2->string . ' != ' . $sim->string . "\n";
- return 1;
- }
-
- # Also exercise invert() while we are at it.
-
- my $inv1 = $set->invert->simplify;
- return threads->new(sub {
- my $inv2 = $sim->invert->simplify;
- return threads->new(sub {
- if ($inv1 != $inv2)
- {
- print " (S3) " . $set->string . ", " . $sim->string . "\n\t"
- . $inv1->string . ' -= ' . $inv2->string . "\n";
- return 1;
- }
- })->join;
- })->join;
- })->join;
- })->join;
- })->join;
- })->join;
- }
-
- return 0;
-}
-
-sub test_sub_conditions ()
-{
- my @tests = ([[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["FOO_FALSE"]],
- ["FOO_TRUE"],
- [["BAR_FALSE", "BAZ_FALSE"],
- ["BAR_FALSE", "BAZ_TRUE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["FOO_FALSE"]],
- ["FOO_TRUE", "BAR_FALSE"],
- [["BAZ_FALSE"],
- ["BAZ_TRUE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
- ["FOO_FALSE"]],
- ["FOO_TRUE", "BAR_TRUE"],
- [["FALSE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
- ["FOO_TRUE", "BAZ_TRUE"],
- ["FOO_FALSE"]],
- ["FOO_TRUE", "BAR_TRUE"],
- [["BAZ_TRUE"]]],
-
- [[["FOO_TRUE", "BAR_FALSE"],
- ["FOO_TRUE", "BAR_TRUE"]],
- ["FOO_TRUE", "BAR_TRUE"],
- [["TRUE"]]],
-
- [[["TRUE"]],
- ["TRUE"],
- [["TRUE"]]],
-
- [[["FALSE"]],
- ["TRUE"],
- [["FALSE"]]],
-
- [[["FALSE"]],
- ["FALSE"],
- [["FALSE"]]]);
-
- for my $t (@tests)
- {
- my $t1 = build_set @{$t->[0]};
- return 1
- if threads->new(sub {
- my $t2 = new Automake::Condition @{$t->[1]};
- return threads->new(sub {
- my $t3 = build_set @{$t->[2]};
- return threads->new(sub {
-
- # Make sure sub_conditions() yields the expected result.
- my $s = $t1->sub_conditions ($t2);
- threads->new(sub {
- if ($s != $t3)
- {
- print " (SC) " . $t1->string . "\n\t"
- . $s->string . ' != ' . $t3->string . "\n";
- return 1;
- }
- })->join;
- })->join;
- })->join;
- })->join;
- }
-}
-
-sub test_ambig ()
-{
- my @tests = ([[["TRUE"]],
- ["TRUE"],
- "multiply defined"],
- [[["C1_TRUE"]],
- ["C1_TRUE"],
- "multiply defined"],
- [[["TRUE"]],
- ["C1_FALSE"],
- "which includes"],
- [[["C1_TRUE"]],
- ["C1_TRUE", "C2_TRUE"],
- "which includes"],
- [[["C1_TRUE", "C2_TRUE"]],
- ["C2_TRUE"],
- "which is included in"],
- [[["C1_TRUE"]],
- ["C2_TRUE"],
- ''],
- [[["C1_TRUE"],
- ["C2_FALSE"]],
- ["C1_FALSE", "C2_TRUE"],
- '']);
-
- my $failed = 0;
- for my $t (@tests)
- {
- my $t1 = build_set @{$t->[0]};
- $failed = 1
- if threads->new(sub {
- my $t2 = new Automake::Condition @{$t->[1]};
- my $t3 = $t->[2];
- return threads->new(sub {
- my ($ans, $cond) = $t1->ambiguous_p ("FOO", $t2);
- return threads->new(sub {
- if ($t3 && $ans !~ /FOO.*$t3/)
- {
- print " (A1) " . $t1->string . " vs. " . $t2->string . "\n\t"
- . "Error message '$ans' does not match '$t3'\n";
- return 1;
- }
- if (!$t3 && $ans ne '')
- {
- print " (A2) " . $t1->string . " vs. " . $t2->string . "\n\t"
- . "Unexpected error message: $ans\n";
- return 1;
- }
- })->join;
- })->join;
- })->join;
- }
- return $failed;
-}
-
-exit (test_basics
- || test_invert
- || test_simplify
- || test_sub_conditions
- || test_ambig);
-
-### Setup "GNU" style for perl-mode and cperl-mode.
-## Local Variables:
-## perl-indent-level: 2
-## perl-continued-statement-offset: 2
-## perl-continued-brace-offset: 0
-## perl-brace-offset: 0
-## perl-brace-imaginary-offset: 0
-## perl-label-offset: -2
-## cperl-indent-level: 2
-## cperl-brace-offset: 0
-## cperl-continued-brace-offset: 0
-## cperl-label-offset: -2
-## cperl-extra-newline-before-brace: t
-## cperl-merge-trailing-else: nil
-## cperl-continued-statement-offset: 2
-## End:
END
$ACLOCAL
-
-# The issue would not manifest with threaded execution.
-unset AUTOMAKE_JOBS || :
-AUTOMAKE_run -Wno-error
-grep 'VAR multiply defined' stderr
-
-AUTOMAKE_JOBS=2
-export AUTOMAKE_JOBS
AUTOMAKE_run -Wno-error
grep 'VAR multiply defined' stderr