From 01df93abe830837cd5d8c4f67e121a94c277427a Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Tue, 29 Nov 2011 10:59:09 -0500 Subject: [PATCH 01/11] Check for allowable Xcode version before generating %p --- bootstrap | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/bootstrap b/bootstrap index c5020e6e3..8fc3e6067 100755 --- a/bootstrap +++ b/bootstrap @@ -316,6 +316,29 @@ if (-x "/usr/bin/head") { exit 1; } + +print "Verifying that installed Xcode version is supported..."; +{ + use Fink::version; # replace with 'use version' once 10.5 is no longer supported + # minimum Xcode versions: + my ($min_xcode, $xc_version); + + if ($vers == 9) { + $min_xcode = '3.0'; + } elsif ($vers == 10) { + $min_xcode = '3.2'; + } else { + $min_xcode = '4.1'; + } + die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); + $xc_version = qv((split /\s/, (split /\n/,`xcodebuild -version`)[0] )[1]); + if (qv($xc_version) gt qv($min_xcode)) { + print "$xc_version is OK.\n"; + } else { + die "ERROR.\nXcode $xc_version is unsupported on this OS X version..\nYou need at least Xcode $min_xcode.\n"; + } +} + ### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # From 0ca1c9742a0f75b264e038985c04734d3b0881f0 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Tue, 29 Nov 2011 12:55:51 -0500 Subject: [PATCH 02/11] Version string check needs to have these. --- perlmod/Fink/version.pm | 72 +++++ perlmod/Fink/version/vpp.pm | 534 ++++++++++++++++++++++++++++++++++++ 2 files changed, 606 insertions(+) create mode 100644 perlmod/Fink/version.pm create mode 100644 perlmod/Fink/version/vpp.pm diff --git a/perlmod/Fink/version.pm b/perlmod/Fink/version.pm new file mode 100644 index 000000000..7c43fd9d7 --- /dev/null +++ b/perlmod/Fink/version.pm @@ -0,0 +1,72 @@ +# This file is based on version from version-0.7203 from CPAN, which +# declares: +# +# This module can be distributed under the same terms as Perl. +# Copyright (C) 2004,2005,2006,2007 John Peacock +# +# For the changes by Fink: +# Copyright (C) 2007-2011 The Fink Package Manager Team. +# 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 +# of the License, or (at your option) any later version. +# +# It was converted to Fink::version and further modified for use by +# Fink. You can read about these changes in the accompanying ChangeLog +# files and by browsing the CVS repository. + +=head1 NAME + +Fink::version - Perl extension for Version Objects + +=head1 SYNOPSIS + +This module is a clone of the L module and its perl-only +back-end implementation. See documentation for those modules. + +=cut + +package Fink::version; + +use 5.005_04; +use strict; + +use vars qw(@ISA $VERSION $CLASS *qv); + +$VERSION = 0.7203; + +$CLASS = 'Fink::version'; + +eval "use Fink::version::vxs $VERSION"; +if ( $@ ) { # don't have the XS version installed + eval "use Fink::version::vpp $VERSION"; # don't tempt fate + die "$@" if ( $@ ); + push @ISA, "Fink::version::vpp"; + *Fink::version::qv = \&Fink::version::vpp::qv; +} +else { # use XS module + push @ISA, "Fink::version::vxs"; + *Fink::version::qv = \&Fink::version::vxs::qv; +} + +# Preloaded methods go here. +sub import { + my ($class) = shift; + my $callpkg = caller(); + no strict 'refs'; + + *{$callpkg."::qv"} = + sub {return bless Fink::version::qv(shift), $class } + unless defined(&{"$callpkg\::qv"}); + +# if (@_) { # must have initialization on the use line +# if ( defined $_[2] ) { # CVS style +# $_[0] = Fink::version::qv($_[2]); +# } +# else { +# $_[0] = Fink::version->new($_[1]); +# } +# } +} + +1; diff --git a/perlmod/Fink/version/vpp.pm b/perlmod/Fink/version/vpp.pm new file mode 100644 index 000000000..1950f3433 --- /dev/null +++ b/perlmod/Fink/version/vpp.pm @@ -0,0 +1,534 @@ +# This file is based on vpp.pm from version-0.7203 from CPAN, which +# declares: +# +# This module can be distributed under the same terms as Perl. +# Copyright (C) 2004,2005,2006,2007 John Peacock +# +# For the changes by Fink: +# Copyright (C) 2007-2011 The Fink Package Manager Team. +# 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 +# of the License, or (at your option) any later version. +# +# It was converted to Fink::version::vpp and further modified for use by +# Fink. You can read about these changes in the accompanying ChangeLog +# files and by browsing the CVS repository. + +package Fink::version::vpp; +use strict; + +use locale; +use vars qw ($VERSION @ISA @REGEXS); +$VERSION = 0.7203; + +push @REGEXS, qr/ + ^v? # optional leading 'v' + (\d*) # major revision not required + \. # requires at least one decimal + (?:(\d+)\.?){1,} + /x; + +use overload ( + '""' => \&stringify, + '0+' => \&numify, + 'cmp' => \&vcmp, + '<=>' => \&vcmp, + 'bool' => \&vbool, + 'nomethod' => \&vnoop, +); + +sub new +{ + my ($class, $value) = @_; + my $self = bless ({}, ref ($class) || $class); + + if ( ref($value) && eval("$value->isa('Fink::version')") ) { + # Can copy the elements directly + $self->{version} = [ @{$value->{version} } ]; + $self->{qv} = 1 if $value->{qv}; + $self->{alpha} = 1 if $value->{alpha}; + $self->{original} = ''.$value->{original}; + return $self; + } + + require POSIX; + my $currlocale = POSIX::setlocale(&POSIX::LC_ALL); + my $radix_comma = ( POSIX::localeconv()->{decimal_point} eq ',' ); + + if ( not defined $value or $value =~ /^undef$/ ) { + # RT #19517 - special case for undef comparison + # or someone forgot to pass a value + push @{$self->{version}}, 0; + $self->{original} = "0"; + return ($self); + } + + if ( $#_ == 2 ) { # must be CVS-style + $value = 'v'.$_[2]; + } + + $value = _un_vstring($value); + + # exponential notation + if ( $value =~ /\d+.?\d*e-?\d+/ ) { + $value = sprintf("%.9f",$value); + $value =~ s/(0+)$//; + } + + # if the original locale used commas for decimal points, we + # just replace commas with decimal places, rather than changing + # locales + if ( $radix_comma ) { + $value =~ tr/,/./; + } + + # This is not very efficient, but it is morally equivalent + # to the XS code (as that is the reference implementation). + # See vutil/vutil.c for details + my $qv = 0; + my $alpha = 0; + my $width = 3; + my $saw_period = 0; + my ($start, $last, $pos, $s); + $s = 0; + + while ( substr($value,$s,1) =~ /\s/ ) { # leading whitespace is OK + $s++; + } + + if (substr($value,$s,1) eq 'v') { + $s++; # get past 'v' + $qv = 1; # force quoted version processing + } + + $start = $last = $pos = $s; + + # pre-scan the input string to check for decimals/underbars + while ( substr($value,$pos,1) =~ /[._\d]/ ) { + if ( substr($value,$pos,1) eq '.' ) { + if ($alpha) { + require Carp; + Carp::croak("Invalid version format ". + "(underscores before decimal)"); + } + $saw_period++; + $last = $pos; + } + elsif ( substr($value,$pos,1) eq '_' ) { + if ($alpha) { + require Carp; + Carp::croak("Invalid version format ". + "(multiple underscores)"); + } + $alpha = 1; + $width = $pos - $last - 1; # natural width of sub-version + } + $pos++; + } + + if ( $alpha && !$saw_period ) { + require Carp; + Carp::croak("Invalid version format (alpha without decimal)"); + } + + if ( $alpha && $saw_period && $width == 0 ) { + require Carp; + Carp::croak("Invalid version format (misplaced _ in number)"); + } + + if ( $saw_period > 1 ) { + $qv = 1; # force quoted version processing + } + + $pos = $s; + + if ( $qv ) { + $self->{qv} = 1; + } + + if ( $alpha ) { + $self->{alpha} = 1; + } + + if ( !$qv && $width < 3 ) { + $self->{width} = $width; + } + + while ( substr($value,$pos,1) =~ /\d/ ) { + $pos++; + } + + if ( substr($value,$pos,1) !~ /[a-z]/ ) { ### FIX THIS ### + my $rev; + + while (1) { + $rev = 0; + { + + # this is atoi() that delimits on underscores + my $end = $pos; + my $mult = 1; + my $orev; + + # the following if() will only be true after the decimal + # point of a version originally created with a bare + # floating point number, i.e. not quoted in any way + if ( !$qv && $s > $start && $saw_period == 1 ) { + $mult *= 100; + while ( $s < $end ) { + $orev = $rev; + $rev += substr($value,$s,1) * $mult; + $mult /= 10; + if ( abs($orev) > abs($rev) ) { + require Carp; + Carp::croak("Integer overflow in version"); + } + $s++; + if ( substr($value,$s,1) eq '_' ) { + $s++; + } + } + } + else { + while (--$end >= $s) { + $orev = $rev; + $rev += substr($value,$end,1) * $mult; + $mult *= 10; + if ( abs($orev) > abs($rev) ) { + require Carp; + Carp::croak("Integer overflow in version"); + } + } + } + } + + # Append revision + push @{$self->{version}}, $rev; + if ( substr($value,$pos,1) eq '.' + && substr($value,$pos+1,1) =~ /\d/ ) { + $s = ++$pos; + } + elsif ( substr($value,$pos,1) eq '_' + && substr($value,$pos+1,1) =~ /\d/ ) { + $s = ++$pos; + } + elsif ( substr($value,$pos,1) =~ /\d/ ) { + $s = $pos; + } + else { + $s = $pos; + last; + } + if ( $qv ) { + while ( substr($value,$pos,1) =~ /\d/ ) { + $pos++; + } + } + else { + my $digits = 0; + while (substr($value,$pos,1) =~ /[\d_]/ && $digits < 3) { + if ( substr($value,$pos,1) ne '_' ) { + $digits++; + } + $pos++; + } + } + } + } + if ( $qv ) { # quoted versions always get at least three terms + my $len = scalar @{$self->{version}}; + $len = 3 - $len; + while ($len-- > 0) { + push @{$self->{version}}, 0; + } + } + + if ( substr($value,$pos) ) { # any remaining text + warn "Version string '$value' contains invalid data; ". + "ignoring: '".substr($value,$pos)."'"; + } + + # cache the original value for use when stringification + $self->{original} = substr($value,0,$pos); + + return ($self); +} + +sub numify +{ + my ($self) = @_; + unless (_verify($self)) { + require Carp; + Carp::croak("Invalid version object"); + } + my $width = $self->{width} || 3; + my $alpha = $self->{alpha} || ""; + my $len = $#{$self->{version}}; + my $digit = $self->{version}[0]; + my $string = sprintf("%d.", $digit ); + + for ( my $i = 1 ; $i < $len ; $i++ ) { + $digit = $self->{version}[$i]; + if ( $width < 3 ) { + my $denom = 10**(3-$width); + my $quot = int($digit/$denom); + my $rem = $digit - ($quot * $denom); + $string .= sprintf("%0".$width."d_%d", $quot, $rem); + } + else { + $string .= sprintf("%03d", $digit); + } + } + + if ( $len > 0 ) { + $digit = $self->{version}[$len]; + if ( $alpha && $width == 3 ) { + $string .= "_"; + } + $string .= sprintf("%0".$width."d", $digit); + } + else # $len = 0 + { + $string .= sprintf("000"); + } + + return $string; +} + +sub normal +{ + my ($self) = @_; + unless (_verify($self)) { + require Carp; + Carp::croak("Invalid version object"); + } + my $alpha = $self->{alpha} || ""; + my $len = $#{$self->{version}}; + my $digit = $self->{version}[0]; + my $string = sprintf("v%d", $digit ); + + for ( my $i = 1 ; $i < $len ; $i++ ) { + $digit = $self->{version}[$i]; + $string .= sprintf(".%d", $digit); + } + + if ( $len > 0 ) { + $digit = $self->{version}[$len]; + if ( $alpha ) { + $string .= sprintf("_%0d", $digit); + } + else { + $string .= sprintf(".%0d", $digit); + } + } + + if ( $len <= 2 ) { + for ( $len = 2 - $len; $len != 0; $len-- ) { + $string .= sprintf(".%0d", 0); + } + } + + return $string; +} + +sub stringify +{ + my ($self) = @_; + unless (_verify($self)) { + require Carp; + Carp::croak("Invalid version object"); + } + return $self->{original}; +} + +sub vcmp +{ + require UNIVERSAL; + my ($left,$right,$swap) = @_; + my $class = ref($left); + unless ( UNIVERSAL::isa($right, $class) ) { + $right = $class->new($right); + } + + if ( $swap ) { + ($left, $right) = ($right, $left); + } + unless (_verify($left)) { + require Carp; + Carp::croak("Invalid version object"); + } + unless (_verify($right)) { + require Carp; + Carp::croak("Invalid version object"); + } + my $l = $#{$left->{version}}; + my $r = $#{$right->{version}}; + my $m = $l < $r ? $l : $r; + my $lalpha = $left->is_alpha; + my $ralpha = $right->is_alpha; + my $retval = 0; + my $i = 0; + while ( $i <= $m && $retval == 0 ) { + $retval = $left->{version}[$i] <=> $right->{version}[$i]; + $i++; + } + + # tiebreaker for alpha with identical terms + if ( $retval == 0 + && $l == $r + && $left->{version}[$m] == $right->{version}[$m] + && ( $lalpha || $ralpha ) ) { + + if ( $lalpha && !$ralpha ) { + $retval = -1; + } + elsif ( $ralpha && !$lalpha) { + $retval = +1; + } + } + + # possible match except for trailing 0's + if ( $retval == 0 && $l != $r ) { + if ( $l < $r ) { + while ( $i <= $r && $retval == 0 ) { + if ( $right->{version}[$i] != 0 ) { + $retval = -1; # not a match after all + } + $i++; + } + } + else { + while ( $i <= $l && $retval == 0 ) { + if ( $left->{version}[$i] != 0 ) { + $retval = +1; # not a match after all + } + $i++; + } + } + } + + return $retval; +} + +sub vbool { + my ($self) = @_; + return vcmp($self,$self->new("0"),1); +} + +sub vnoop { + require Carp; + Carp::croak("operation not supported with version object"); +} + +sub is_alpha { + my ($self) = @_; + return (exists $self->{alpha}); +} + +sub qv { + my ($value) = @_; + + $value = _un_vstring($value); + $value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/; + my $version = Fink::version->new($value); # always use base class + return $version; +} + +sub is_qv { + my ($self) = @_; + return (exists $self->{qv}); +} + + +sub _verify { + my ($self) = @_; + if ( ref($self) + && eval { exists $self->{version} } + && ref($self->{version}) eq 'ARRAY' + ) { + return 1; + } + else { + return 0; + } +} + +sub _un_vstring { + my $value = shift; + # may be a v-string + if ( $] >= 5.006_000 && length($value) >= 3 && $value !~ /[._]/ ) { + my $tvalue = sprintf("v%vd",$value); + if ( $tvalue =~ /^v\d+\.\d+\.\d+$/ ) { + # must be a v-string + $value = $tvalue; + } + } + return $value; +} + +# Thanks to Yitzchak Scott-Thoennes for this mode of operation +{ + local $^W; + *UNIVERSAL::VERSION = sub { + my ($obj, $req) = @_; + my $class = ref($obj) || $obj; + + no strict 'refs'; + eval "require $class" unless %{"$class\::"}; # already existing + return undef if $@ =~ /Can't locate/ and not defined $req; + + if ( not %{"$class\::"} and $] >= 5.008) { # file but no package + require Carp; + Carp::croak( "$class defines neither package nor VERSION" + ."--version check failed"); + } + + my $version = eval "\$$class\::VERSION"; + if ( defined $version ) { + local $^W if $] <= 5.008; + $version = Fink::version::vpp->new($version); + } + + if ( defined $req ) { + unless ( defined $version ) { + require Carp; + my $msg = $] < 5.006 + ? "$class version $req required--this is only version " + : "$class does not define \$$class\::VERSION" + ."--version check failed"; + + if ( $ENV{VERSION_DEBUG} ) { + Carp::confess($msg); + } + else { + Carp::croak($msg); + } + } + + $req = Fink::version::vpp->new($req); + + if ( $req > $version ) { + require Carp; + if ( $req->is_qv ) { + Carp::croak( + sprintf ("%s version %s required--". + "this is only version %s", $class, + $req->normal, $version->normal) + ); + } + else { + Carp::croak( + sprintf ("%s version %s required--". + "this is only version %s", $class, + $req->stringify, $version->stringify) + ); + } + } + } + + return defined $version ? $version->stringify : undef; + }; +} + +1; #this line is important and will help the module return a true value From d9f0ad604538ec2e2353ae671f830b755f6d0630 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 09:54:56 -0500 Subject: [PATCH 03/11] Revert "Version string check needs to have these." This reverts commit 0ca1c9742a0f75b264e038985c04734d3b0881f0. --- perlmod/Fink/version.pm | 72 ----- perlmod/Fink/version/vpp.pm | 534 ------------------------------------ 2 files changed, 606 deletions(-) delete mode 100644 perlmod/Fink/version.pm delete mode 100644 perlmod/Fink/version/vpp.pm diff --git a/perlmod/Fink/version.pm b/perlmod/Fink/version.pm deleted file mode 100644 index 7c43fd9d7..000000000 --- a/perlmod/Fink/version.pm +++ /dev/null @@ -1,72 +0,0 @@ -# This file is based on version from version-0.7203 from CPAN, which -# declares: -# -# This module can be distributed under the same terms as Perl. -# Copyright (C) 2004,2005,2006,2007 John Peacock -# -# For the changes by Fink: -# Copyright (C) 2007-2011 The Fink Package Manager Team. -# 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 -# of the License, or (at your option) any later version. -# -# It was converted to Fink::version and further modified for use by -# Fink. You can read about these changes in the accompanying ChangeLog -# files and by browsing the CVS repository. - -=head1 NAME - -Fink::version - Perl extension for Version Objects - -=head1 SYNOPSIS - -This module is a clone of the L module and its perl-only -back-end implementation. See documentation for those modules. - -=cut - -package Fink::version; - -use 5.005_04; -use strict; - -use vars qw(@ISA $VERSION $CLASS *qv); - -$VERSION = 0.7203; - -$CLASS = 'Fink::version'; - -eval "use Fink::version::vxs $VERSION"; -if ( $@ ) { # don't have the XS version installed - eval "use Fink::version::vpp $VERSION"; # don't tempt fate - die "$@" if ( $@ ); - push @ISA, "Fink::version::vpp"; - *Fink::version::qv = \&Fink::version::vpp::qv; -} -else { # use XS module - push @ISA, "Fink::version::vxs"; - *Fink::version::qv = \&Fink::version::vxs::qv; -} - -# Preloaded methods go here. -sub import { - my ($class) = shift; - my $callpkg = caller(); - no strict 'refs'; - - *{$callpkg."::qv"} = - sub {return bless Fink::version::qv(shift), $class } - unless defined(&{"$callpkg\::qv"}); - -# if (@_) { # must have initialization on the use line -# if ( defined $_[2] ) { # CVS style -# $_[0] = Fink::version::qv($_[2]); -# } -# else { -# $_[0] = Fink::version->new($_[1]); -# } -# } -} - -1; diff --git a/perlmod/Fink/version/vpp.pm b/perlmod/Fink/version/vpp.pm deleted file mode 100644 index 1950f3433..000000000 --- a/perlmod/Fink/version/vpp.pm +++ /dev/null @@ -1,534 +0,0 @@ -# This file is based on vpp.pm from version-0.7203 from CPAN, which -# declares: -# -# This module can be distributed under the same terms as Perl. -# Copyright (C) 2004,2005,2006,2007 John Peacock -# -# For the changes by Fink: -# Copyright (C) 2007-2011 The Fink Package Manager Team. -# 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 -# of the License, or (at your option) any later version. -# -# It was converted to Fink::version::vpp and further modified for use by -# Fink. You can read about these changes in the accompanying ChangeLog -# files and by browsing the CVS repository. - -package Fink::version::vpp; -use strict; - -use locale; -use vars qw ($VERSION @ISA @REGEXS); -$VERSION = 0.7203; - -push @REGEXS, qr/ - ^v? # optional leading 'v' - (\d*) # major revision not required - \. # requires at least one decimal - (?:(\d+)\.?){1,} - /x; - -use overload ( - '""' => \&stringify, - '0+' => \&numify, - 'cmp' => \&vcmp, - '<=>' => \&vcmp, - 'bool' => \&vbool, - 'nomethod' => \&vnoop, -); - -sub new -{ - my ($class, $value) = @_; - my $self = bless ({}, ref ($class) || $class); - - if ( ref($value) && eval("$value->isa('Fink::version')") ) { - # Can copy the elements directly - $self->{version} = [ @{$value->{version} } ]; - $self->{qv} = 1 if $value->{qv}; - $self->{alpha} = 1 if $value->{alpha}; - $self->{original} = ''.$value->{original}; - return $self; - } - - require POSIX; - my $currlocale = POSIX::setlocale(&POSIX::LC_ALL); - my $radix_comma = ( POSIX::localeconv()->{decimal_point} eq ',' ); - - if ( not defined $value or $value =~ /^undef$/ ) { - # RT #19517 - special case for undef comparison - # or someone forgot to pass a value - push @{$self->{version}}, 0; - $self->{original} = "0"; - return ($self); - } - - if ( $#_ == 2 ) { # must be CVS-style - $value = 'v'.$_[2]; - } - - $value = _un_vstring($value); - - # exponential notation - if ( $value =~ /\d+.?\d*e-?\d+/ ) { - $value = sprintf("%.9f",$value); - $value =~ s/(0+)$//; - } - - # if the original locale used commas for decimal points, we - # just replace commas with decimal places, rather than changing - # locales - if ( $radix_comma ) { - $value =~ tr/,/./; - } - - # This is not very efficient, but it is morally equivalent - # to the XS code (as that is the reference implementation). - # See vutil/vutil.c for details - my $qv = 0; - my $alpha = 0; - my $width = 3; - my $saw_period = 0; - my ($start, $last, $pos, $s); - $s = 0; - - while ( substr($value,$s,1) =~ /\s/ ) { # leading whitespace is OK - $s++; - } - - if (substr($value,$s,1) eq 'v') { - $s++; # get past 'v' - $qv = 1; # force quoted version processing - } - - $start = $last = $pos = $s; - - # pre-scan the input string to check for decimals/underbars - while ( substr($value,$pos,1) =~ /[._\d]/ ) { - if ( substr($value,$pos,1) eq '.' ) { - if ($alpha) { - require Carp; - Carp::croak("Invalid version format ". - "(underscores before decimal)"); - } - $saw_period++; - $last = $pos; - } - elsif ( substr($value,$pos,1) eq '_' ) { - if ($alpha) { - require Carp; - Carp::croak("Invalid version format ". - "(multiple underscores)"); - } - $alpha = 1; - $width = $pos - $last - 1; # natural width of sub-version - } - $pos++; - } - - if ( $alpha && !$saw_period ) { - require Carp; - Carp::croak("Invalid version format (alpha without decimal)"); - } - - if ( $alpha && $saw_period && $width == 0 ) { - require Carp; - Carp::croak("Invalid version format (misplaced _ in number)"); - } - - if ( $saw_period > 1 ) { - $qv = 1; # force quoted version processing - } - - $pos = $s; - - if ( $qv ) { - $self->{qv} = 1; - } - - if ( $alpha ) { - $self->{alpha} = 1; - } - - if ( !$qv && $width < 3 ) { - $self->{width} = $width; - } - - while ( substr($value,$pos,1) =~ /\d/ ) { - $pos++; - } - - if ( substr($value,$pos,1) !~ /[a-z]/ ) { ### FIX THIS ### - my $rev; - - while (1) { - $rev = 0; - { - - # this is atoi() that delimits on underscores - my $end = $pos; - my $mult = 1; - my $orev; - - # the following if() will only be true after the decimal - # point of a version originally created with a bare - # floating point number, i.e. not quoted in any way - if ( !$qv && $s > $start && $saw_period == 1 ) { - $mult *= 100; - while ( $s < $end ) { - $orev = $rev; - $rev += substr($value,$s,1) * $mult; - $mult /= 10; - if ( abs($orev) > abs($rev) ) { - require Carp; - Carp::croak("Integer overflow in version"); - } - $s++; - if ( substr($value,$s,1) eq '_' ) { - $s++; - } - } - } - else { - while (--$end >= $s) { - $orev = $rev; - $rev += substr($value,$end,1) * $mult; - $mult *= 10; - if ( abs($orev) > abs($rev) ) { - require Carp; - Carp::croak("Integer overflow in version"); - } - } - } - } - - # Append revision - push @{$self->{version}}, $rev; - if ( substr($value,$pos,1) eq '.' - && substr($value,$pos+1,1) =~ /\d/ ) { - $s = ++$pos; - } - elsif ( substr($value,$pos,1) eq '_' - && substr($value,$pos+1,1) =~ /\d/ ) { - $s = ++$pos; - } - elsif ( substr($value,$pos,1) =~ /\d/ ) { - $s = $pos; - } - else { - $s = $pos; - last; - } - if ( $qv ) { - while ( substr($value,$pos,1) =~ /\d/ ) { - $pos++; - } - } - else { - my $digits = 0; - while (substr($value,$pos,1) =~ /[\d_]/ && $digits < 3) { - if ( substr($value,$pos,1) ne '_' ) { - $digits++; - } - $pos++; - } - } - } - } - if ( $qv ) { # quoted versions always get at least three terms - my $len = scalar @{$self->{version}}; - $len = 3 - $len; - while ($len-- > 0) { - push @{$self->{version}}, 0; - } - } - - if ( substr($value,$pos) ) { # any remaining text - warn "Version string '$value' contains invalid data; ". - "ignoring: '".substr($value,$pos)."'"; - } - - # cache the original value for use when stringification - $self->{original} = substr($value,0,$pos); - - return ($self); -} - -sub numify -{ - my ($self) = @_; - unless (_verify($self)) { - require Carp; - Carp::croak("Invalid version object"); - } - my $width = $self->{width} || 3; - my $alpha = $self->{alpha} || ""; - my $len = $#{$self->{version}}; - my $digit = $self->{version}[0]; - my $string = sprintf("%d.", $digit ); - - for ( my $i = 1 ; $i < $len ; $i++ ) { - $digit = $self->{version}[$i]; - if ( $width < 3 ) { - my $denom = 10**(3-$width); - my $quot = int($digit/$denom); - my $rem = $digit - ($quot * $denom); - $string .= sprintf("%0".$width."d_%d", $quot, $rem); - } - else { - $string .= sprintf("%03d", $digit); - } - } - - if ( $len > 0 ) { - $digit = $self->{version}[$len]; - if ( $alpha && $width == 3 ) { - $string .= "_"; - } - $string .= sprintf("%0".$width."d", $digit); - } - else # $len = 0 - { - $string .= sprintf("000"); - } - - return $string; -} - -sub normal -{ - my ($self) = @_; - unless (_verify($self)) { - require Carp; - Carp::croak("Invalid version object"); - } - my $alpha = $self->{alpha} || ""; - my $len = $#{$self->{version}}; - my $digit = $self->{version}[0]; - my $string = sprintf("v%d", $digit ); - - for ( my $i = 1 ; $i < $len ; $i++ ) { - $digit = $self->{version}[$i]; - $string .= sprintf(".%d", $digit); - } - - if ( $len > 0 ) { - $digit = $self->{version}[$len]; - if ( $alpha ) { - $string .= sprintf("_%0d", $digit); - } - else { - $string .= sprintf(".%0d", $digit); - } - } - - if ( $len <= 2 ) { - for ( $len = 2 - $len; $len != 0; $len-- ) { - $string .= sprintf(".%0d", 0); - } - } - - return $string; -} - -sub stringify -{ - my ($self) = @_; - unless (_verify($self)) { - require Carp; - Carp::croak("Invalid version object"); - } - return $self->{original}; -} - -sub vcmp -{ - require UNIVERSAL; - my ($left,$right,$swap) = @_; - my $class = ref($left); - unless ( UNIVERSAL::isa($right, $class) ) { - $right = $class->new($right); - } - - if ( $swap ) { - ($left, $right) = ($right, $left); - } - unless (_verify($left)) { - require Carp; - Carp::croak("Invalid version object"); - } - unless (_verify($right)) { - require Carp; - Carp::croak("Invalid version object"); - } - my $l = $#{$left->{version}}; - my $r = $#{$right->{version}}; - my $m = $l < $r ? $l : $r; - my $lalpha = $left->is_alpha; - my $ralpha = $right->is_alpha; - my $retval = 0; - my $i = 0; - while ( $i <= $m && $retval == 0 ) { - $retval = $left->{version}[$i] <=> $right->{version}[$i]; - $i++; - } - - # tiebreaker for alpha with identical terms - if ( $retval == 0 - && $l == $r - && $left->{version}[$m] == $right->{version}[$m] - && ( $lalpha || $ralpha ) ) { - - if ( $lalpha && !$ralpha ) { - $retval = -1; - } - elsif ( $ralpha && !$lalpha) { - $retval = +1; - } - } - - # possible match except for trailing 0's - if ( $retval == 0 && $l != $r ) { - if ( $l < $r ) { - while ( $i <= $r && $retval == 0 ) { - if ( $right->{version}[$i] != 0 ) { - $retval = -1; # not a match after all - } - $i++; - } - } - else { - while ( $i <= $l && $retval == 0 ) { - if ( $left->{version}[$i] != 0 ) { - $retval = +1; # not a match after all - } - $i++; - } - } - } - - return $retval; -} - -sub vbool { - my ($self) = @_; - return vcmp($self,$self->new("0"),1); -} - -sub vnoop { - require Carp; - Carp::croak("operation not supported with version object"); -} - -sub is_alpha { - my ($self) = @_; - return (exists $self->{alpha}); -} - -sub qv { - my ($value) = @_; - - $value = _un_vstring($value); - $value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/; - my $version = Fink::version->new($value); # always use base class - return $version; -} - -sub is_qv { - my ($self) = @_; - return (exists $self->{qv}); -} - - -sub _verify { - my ($self) = @_; - if ( ref($self) - && eval { exists $self->{version} } - && ref($self->{version}) eq 'ARRAY' - ) { - return 1; - } - else { - return 0; - } -} - -sub _un_vstring { - my $value = shift; - # may be a v-string - if ( $] >= 5.006_000 && length($value) >= 3 && $value !~ /[._]/ ) { - my $tvalue = sprintf("v%vd",$value); - if ( $tvalue =~ /^v\d+\.\d+\.\d+$/ ) { - # must be a v-string - $value = $tvalue; - } - } - return $value; -} - -# Thanks to Yitzchak Scott-Thoennes for this mode of operation -{ - local $^W; - *UNIVERSAL::VERSION = sub { - my ($obj, $req) = @_; - my $class = ref($obj) || $obj; - - no strict 'refs'; - eval "require $class" unless %{"$class\::"}; # already existing - return undef if $@ =~ /Can't locate/ and not defined $req; - - if ( not %{"$class\::"} and $] >= 5.008) { # file but no package - require Carp; - Carp::croak( "$class defines neither package nor VERSION" - ."--version check failed"); - } - - my $version = eval "\$$class\::VERSION"; - if ( defined $version ) { - local $^W if $] <= 5.008; - $version = Fink::version::vpp->new($version); - } - - if ( defined $req ) { - unless ( defined $version ) { - require Carp; - my $msg = $] < 5.006 - ? "$class version $req required--this is only version " - : "$class does not define \$$class\::VERSION" - ."--version check failed"; - - if ( $ENV{VERSION_DEBUG} ) { - Carp::confess($msg); - } - else { - Carp::croak($msg); - } - } - - $req = Fink::version::vpp->new($req); - - if ( $req > $version ) { - require Carp; - if ( $req->is_qv ) { - Carp::croak( - sprintf ("%s version %s required--". - "this is only version %s", $class, - $req->normal, $version->normal) - ); - } - else { - Carp::croak( - sprintf ("%s version %s required--". - "this is only version %s", $class, - $req->stringify, $version->stringify) - ); - } - } - } - - return defined $version ? $version->stringify : undef; - }; -} - -1; #this line is important and will help the module return a true value From 0e826f4151991a65d730a8e1b445c505438c8b7f Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 09:56:49 -0500 Subject: [PATCH 04/11] Revert "Check for allowable Xcode version before generating %p" This reverts commit 01df93abe830837cd5d8c4f67e121a94c277427a. --- bootstrap | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/bootstrap b/bootstrap index 8fc3e6067..c5020e6e3 100755 --- a/bootstrap +++ b/bootstrap @@ -316,29 +316,6 @@ if (-x "/usr/bin/head") { exit 1; } - -print "Verifying that installed Xcode version is supported..."; -{ - use Fink::version; # replace with 'use version' once 10.5 is no longer supported - # minimum Xcode versions: - my ($min_xcode, $xc_version); - - if ($vers == 9) { - $min_xcode = '3.0'; - } elsif ($vers == 10) { - $min_xcode = '3.2'; - } else { - $min_xcode = '4.1'; - } - die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); - $xc_version = qv((split /\s/, (split /\n/,`xcodebuild -version`)[0] )[1]); - if (qv($xc_version) gt qv($min_xcode)) { - print "$xc_version is OK.\n"; - } else { - die "ERROR.\nXcode $xc_version is unsupported on this OS X version..\nYou need at least Xcode $min_xcode.\n"; - } -} - ### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # From 7a23727f24992f304885c47ea11fcc306262d77b Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 09:58:23 -0500 Subject: [PATCH 05/11] Check for allowable Xcode versions --- bootstrap | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index c5020e6e3..65998a13e 100755 --- a/bootstrap +++ b/bootstrap @@ -316,7 +316,46 @@ if (-x "/usr/bin/head") { exit 1; } -### setup the correct packages directory +## Check for legal Xcode +{ + # Convert Xcode version to an integer and use numeric comparisons (for now). + # Possibly replace with 'use version' once 10.5 is no longer supported + # to be robust against two-digit minor or subminor versions. + + # minimum Xcode versions: + my ($min_xcode, $min_xcode_readable, $max_xcode, $max_xcode_readable, $xc_version); + + if ($vers == 9) { + $min_xcode = 300; + $min_xcode_readable="3.0.0"; + $max_xcode = 314; + $max_xcode_readable="3.1.4"; + } elsif ($vers == 10) { + $min_xcode = 320; + $min_xcode_readable="3.2.0"; + $max_xcode = 490; + $max_xcode_readable="4.9.0"; + } elsif ($vers == 11) { + $min_xcode = 410; + $min_xcode_readable="4.1.0"; + $max_xcode = 490; + $max_xcode_readable="4.9.0"; + } else { + die "ERROR:\n\tUnsupported OS X version.\n"; + } + die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); + { + my ($xc_raw1,$xc_raw2,$xc_raw3) = (`xcodebuild -version` =~ /(\d+)\.(\d+)\.?(\d+)?/) ; + print "Xcode version: $xc_raw1.$xc_raw2.$xc_raw3\n"; + $xc_version=100*$xc_raw1+10*$xc_raw2+$xc_raw3; # make sure we're a 3-digit number + } + + die "ERROR: You need at least Xcode $min_xcode_readable on this OS X version.\n" if $xc_version < $min_xcode ; + die "ERROR: You need at most Xcode $max_xcode_readable on this OS X version.\n" if $xc_version > $max_xcode ; + print "OK.\n"; +} + +## setup the correct packages directory # (no longer needed: we just use $distribution directly...) # #if (-e "packages") { From e1fd56ded78a98e86928e8be8c91d144384bdcc6 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 10:07:47 -0500 Subject: [PATCH 06/11] Revert "Check for allowable Xcode versions" This reverts commit 7a23727f24992f304885c47ea11fcc306262d77b. --- bootstrap | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/bootstrap b/bootstrap index 65998a13e..c5020e6e3 100755 --- a/bootstrap +++ b/bootstrap @@ -316,46 +316,7 @@ if (-x "/usr/bin/head") { exit 1; } -## Check for legal Xcode -{ - # Convert Xcode version to an integer and use numeric comparisons (for now). - # Possibly replace with 'use version' once 10.5 is no longer supported - # to be robust against two-digit minor or subminor versions. - - # minimum Xcode versions: - my ($min_xcode, $min_xcode_readable, $max_xcode, $max_xcode_readable, $xc_version); - - if ($vers == 9) { - $min_xcode = 300; - $min_xcode_readable="3.0.0"; - $max_xcode = 314; - $max_xcode_readable="3.1.4"; - } elsif ($vers == 10) { - $min_xcode = 320; - $min_xcode_readable="3.2.0"; - $max_xcode = 490; - $max_xcode_readable="4.9.0"; - } elsif ($vers == 11) { - $min_xcode = 410; - $min_xcode_readable="4.1.0"; - $max_xcode = 490; - $max_xcode_readable="4.9.0"; - } else { - die "ERROR:\n\tUnsupported OS X version.\n"; - } - die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); - { - my ($xc_raw1,$xc_raw2,$xc_raw3) = (`xcodebuild -version` =~ /(\d+)\.(\d+)\.?(\d+)?/) ; - print "Xcode version: $xc_raw1.$xc_raw2.$xc_raw3\n"; - $xc_version=100*$xc_raw1+10*$xc_raw2+$xc_raw3; # make sure we're a 3-digit number - } - - die "ERROR: You need at least Xcode $min_xcode_readable on this OS X version.\n" if $xc_version < $min_xcode ; - die "ERROR: You need at most Xcode $max_xcode_readable on this OS X version.\n" if $xc_version > $max_xcode ; - print "OK.\n"; -} - -## setup the correct packages directory +### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # #if (-e "packages") { From a26fa17843ac43c5fa0ce04841ecec1d9fe4f696 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 10:10:07 -0500 Subject: [PATCH 07/11] Use numeric check for allowable Xcode versions. --- bootstrap | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/bootstrap b/bootstrap index c5020e6e3..0bc76b40a 100755 --- a/bootstrap +++ b/bootstrap @@ -316,6 +316,45 @@ if (-x "/usr/bin/head") { exit 1; } +### Check for allowable Xcode for OS +{ + # Convert Xcode version to an integer and use numeric comparisons (for now). + # Possibly replace with 'use version' once 10.5 is no longer supported + # to be robust against two-digit minor or subminor versions. + + # minimum Xcode versions: + my ($min_xcode, $min_xcode_readable, $max_xcode, $max_xcode_readable, $xc_version); + + if ($vers == 9) { + $min_xcode = 30; + $min_xcode_readable="3.0"; + $max_xcode = 31; + $max_xcode_readable="3.1"; + } elsif ($vers == 10) { + $min_xcode = 32; + $min_xcode_readable="3.2"; + $max_xcode = 49; + $max_xcode_readable="4.9"; + } elsif ($vers == 11) { + $min_xcode = 41; + $min_xcode_readable="4.1"; + $max_xcode = 49; + $max_xcode_readable="4.9"; + } else { + die "ERROR:\n\tUnsupported OS X version.\n"; + } + die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); + { + my ($xc_raw1,$xc_raw2,$xc_raw3) = (`xcodebuild -version` =~ /(\d+)\.(\d+)\.?(\d+)?/) ; + print "Xcode version: $xc_raw1.$xc_raw2.$xc_raw3\n"; + $xc_version=10*$xc_raw1+$xc_raw2; # make sure we're a 3-digit number + } + + die "ERROR: You need at least Xcode $min_xcode_readable on this OS X version.\n" if $xc_version < $min_xcode ; + die "ERROR: You need at most Xcode $max_xcode_readable on this OS X version.\n" if $xc_version > $max_xcode ; + print "OK.\n"; +} + ### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # From f4df249252a932cd2ee7f6e2c1d837ea36dde69f Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 10:12:44 -0500 Subject: [PATCH 08/11] Revert "Use numeric check for allowable Xcode versions." This reverts commit a26fa17843ac43c5fa0ce04841ecec1d9fe4f696. --- bootstrap | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/bootstrap b/bootstrap index 0bc76b40a..c5020e6e3 100755 --- a/bootstrap +++ b/bootstrap @@ -316,45 +316,6 @@ if (-x "/usr/bin/head") { exit 1; } -### Check for allowable Xcode for OS -{ - # Convert Xcode version to an integer and use numeric comparisons (for now). - # Possibly replace with 'use version' once 10.5 is no longer supported - # to be robust against two-digit minor or subminor versions. - - # minimum Xcode versions: - my ($min_xcode, $min_xcode_readable, $max_xcode, $max_xcode_readable, $xc_version); - - if ($vers == 9) { - $min_xcode = 30; - $min_xcode_readable="3.0"; - $max_xcode = 31; - $max_xcode_readable="3.1"; - } elsif ($vers == 10) { - $min_xcode = 32; - $min_xcode_readable="3.2"; - $max_xcode = 49; - $max_xcode_readable="4.9"; - } elsif ($vers == 11) { - $min_xcode = 41; - $min_xcode_readable="4.1"; - $max_xcode = 49; - $max_xcode_readable="4.9"; - } else { - die "ERROR:\n\tUnsupported OS X version.\n"; - } - die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); - { - my ($xc_raw1,$xc_raw2,$xc_raw3) = (`xcodebuild -version` =~ /(\d+)\.(\d+)\.?(\d+)?/) ; - print "Xcode version: $xc_raw1.$xc_raw2.$xc_raw3\n"; - $xc_version=10*$xc_raw1+$xc_raw2; # make sure we're a 3-digit number - } - - die "ERROR: You need at least Xcode $min_xcode_readable on this OS X version.\n" if $xc_version < $min_xcode ; - die "ERROR: You need at most Xcode $max_xcode_readable on this OS X version.\n" if $xc_version > $max_xcode ; - print "OK.\n"; -} - ### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # From cb65db7055135c431e2f43e978d62bbd293adc46 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Wed, 18 Jan 2012 11:32:57 -0500 Subject: [PATCH 09/11] Xcode version check using Fink::Services::version_cmp() --- bootstrap | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index c5020e6e3..368754b0d 100755 --- a/bootstrap +++ b/bootstrap @@ -41,7 +41,7 @@ unlink "$FindBin::RealBin/perlmod/Fink/FinkVersion.pm"; require Fink::CLI; import Fink::CLI qw(&print_breaking &prompt &prompt_boolean &prompt_selection); require Fink::Services; -import Fink::Services qw(&execute); +import Fink::Services qw(&execute &version_cmp); $| = 1; @@ -316,6 +316,46 @@ if (-x "/usr/bin/head") { exit 1; } +### Check for allowable Xcode +print "Verifying that installed Xcode version is supported...\n"; +{ + # Compare Xcode version to allowed range via Fink::Services::version_cmp(). + # Possibly replace with 'use version', qv() , and the standard comparison + # operators once 10.5 is no longer supported. + + # minimum Xcode versions: + my ($min_xcode, $max_xcode, $xcode_version); + + if ($vers == 9) { + $min_xcode="3.0"; + $max_xcode="3.1.4"; + } elsif ($vers == 10) { + $min_xcode="3.2"; + $max_xcode="4.9"; + } elsif ($vers == 11) { + $min_xcode="4.1"; + $max_xcode="4.9"; + } else { + die "ERROR:\n\tUnsupported OS X version.\n"; + } + die "ERROR:\n\tCan't determine Xcode version.\n" unless (-x "/usr/bin/xcodebuild"); + ($xcode_version) = (`xcodebuild -version` =~ /(\d+\.\d+\.?(\d+)?)/) ; + print "Xcode version: $xcode_version"; + + if (&version_cmp ("$xcode_version", "<<", "$min_xcode")) { + & print_breaking ( "\nERROR: You need at least ". + "Xcode ".$min_xcode." on this OS X version.\n"); + exit 1; + } elsif (&version_cmp ("$xcode_version", ">>", "$max_xcode")) { + & print_breaking ( "\nERROR: You need at most ". + "Xcode ".$max_xcode." on this OS X version.\n"); + exit 1; + } else { + print " is OK.\n"; + } +} + + ### setup the correct packages directory # (no longer needed: we just use $distribution directly...) # From 92b2b2789df94bc5902c177cd080815a651788a9 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Thu, 29 Mar 2012 16:33:15 -0700 Subject: [PATCH 10/11] manually revert --- bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index ad3786293..2255e7107 100755 --- a/bootstrap +++ b/bootstrap @@ -340,7 +340,7 @@ print "Verifying that installed Xcode version is supported...\n"; } # Die if there are no Xcode CLI tools, at minimum. die "ERROR:\n\tNo Xcode command-line tools installed. Install them (or all of Xcode).\n" unless (-x "/usr/bin/xcodebuild"); - ($xcode_version) = (`xcodebuild -version` =~ /Xcode\s(\d+\.\d+\.?(\d+)?)\n/) ; + ($xcode_version) = (`xcodebuild -version` =~ /(\d+\.\d+\.?(\d+)?)/) ; if (!defined $xcode_version) { # OS version specific messages if ($vers < 11) { From 0e6d6a193085b5fc31dacba3284919d433667e4c Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Thu, 29 Mar 2012 16:36:13 -0700 Subject: [PATCH 11/11] Use a robust regex when checking Xcode version. --- bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index 2255e7107..ad3786293 100755 --- a/bootstrap +++ b/bootstrap @@ -340,7 +340,7 @@ print "Verifying that installed Xcode version is supported...\n"; } # Die if there are no Xcode CLI tools, at minimum. die "ERROR:\n\tNo Xcode command-line tools installed. Install them (or all of Xcode).\n" unless (-x "/usr/bin/xcodebuild"); - ($xcode_version) = (`xcodebuild -version` =~ /(\d+\.\d+\.?(\d+)?)/) ; + ($xcode_version) = (`xcodebuild -version` =~ /Xcode\s(\d+\.\d+\.?(\d+)?)\n/) ; if (!defined $xcode_version) { # OS version specific messages if ($vers < 11) {