<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Copyright (C) 2003-2018 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 &lt;https://www.gnu.org/licenses/&gt;.

package Automake::Options;

use 5.006;
use strict;
use Exporter;
use Automake::Config;
use Automake::ChannelDefs;
use Automake::Channels;
use Automake::Version;

use vars qw (@ISA @EXPORT);

@ISA = qw (Exporter);
@EXPORT = qw (option global_option
              set_option set_global_option
              unset_option unset_global_option
              process_option_list process_global_option_list
              set_strictness $strictness $strictness_name
              &amp;FOREIGN &amp;GNU &amp;GNITS);

=head1 NAME

Automake::Options - keep track of Automake options

=head1 SYNOPSIS

  use Automake::Options;

  # Option lookup and setting.
  $opt = option 'name';
  $opt = global_option 'name';
  set_option 'name', 'value';
  set_global_option 'name', 'value';
  unset_option 'name';
  unset_global_option 'name';

  # Batch option setting.
  process_option_list $location, @names;
  process_global_option_list $location, @names;

  # Strictness lookup and setting.
  set_strictness 'foreign';
  set_strictness 'gnu';
  set_strictness 'gnits';
  if ($strictness &gt;= GNU) { ... }
  print "$strictness_name\n";

=head1 DESCRIPTION

This packages manages Automake's options and strictness settings.
Options can be either local or global.  Local options are set using an
C&lt;AUTOMAKE_OPTIONS&gt; variable in a F&lt;Makefile.am&gt; and apply only to
this F&lt;Makefile.am&gt;.  Global options are set from the command line or
passed as an argument to C&lt;AM_INIT_AUTOMAKE&gt;, they apply to all
F&lt;Makefile.am&gt;s.

=cut

# Values are the Automake::Location of the definition.
use vars '%_options';        # From AUTOMAKE_OPTIONS
use vars '%_global_options'; # From AM_INIT_AUTOMAKE or the command line.

# Whether process_option_list has already been called for the current
# Makefile.am.
use vars '$_options_processed';
# Whether process_global_option_list has already been called.
use vars '$_global_options_processed';

=head2 Constants

=over 4

=item FOREIGN

=item GNU

=item GNITS

Strictness constants used as values for C&lt;$strictness&gt;.

=back

=cut

# Constants to define the "strictness" level.
use constant FOREIGN =&gt; 0;
use constant GNU     =&gt; 1;
use constant GNITS   =&gt; 2;

=head2 Variables

=over 4

=item C&lt;$strictness&gt;

The current strictness.  One of C&lt;FOREIGN&gt;, C&lt;GNU&gt;, or C&lt;GNITS&gt;.

=item C&lt;$strictness_name&gt;

The current strictness name.  One of C&lt;'foreign'&gt;, C&lt;'gnu'&gt;, or C&lt;'gnits'&gt;.

=back

=cut

# Strictness levels.
use vars qw ($strictness $strictness_name);

# Strictness level as set on command line.
use vars qw ($_default_strictness $_default_strictness_name);


=head2 Functions

=over 4

=item C&lt;Automake::Options::reset&gt;

Reset the options variables for the next F&lt;Makefile.am&gt;.

In other words, this gets rid of all local options in use by the
previous F&lt;Makefile.am&gt;.

=cut

sub reset ()
{
  $_options_processed = 0;
  %_options = %_global_options;
  # The first time we are run,
  # remember the current setting as the default.
  if (defined $_default_strictness)
    {
      $strictness = $_default_strictness;
      $strictness_name = $_default_strictness_name;
    }
  else
    {
      $_default_strictness = $strictness;
      $_default_strictness_name = $strictness_name;
    }
}

=item C&lt;$value = option ($name)&gt;

=item C&lt;$value = global_option ($name)&gt;

Query the state of an option.  If the option is unset, this
returns the empty list.  Otherwise it returns the option's value,
as set by C&lt;set_option&gt; or C&lt;set_global_option&gt;.

Note that C&lt;global_option&gt; should be used only when it is
important to make sure an option hasn't been set locally.
Otherwise C&lt;option&gt; should be the standard function to
check for options (be they global or local).

=cut

sub option ($)
{
  my ($name) = @_;
  return () unless defined $_options{$name};
  return $_options{$name};
}

sub global_option ($)
{
  my ($name) = @_;
  return () unless defined $_global_options{$name};
  return $_global_options{$name};
}

=item C&lt;set_option ($name, $value)&gt;

=item C&lt;set_global_option ($name, $value)&gt;

Set an option.  By convention, C&lt;$value&gt; is usually the location
of the option definition.

=cut

sub set_option ($$)
{
  my ($name, $value) = @_;
  $_options{$name} = $value;
}

sub set_global_option ($$)
{
  my ($name, $value) = @_;
  $_global_options{$name} = $value;
}


=item C&lt;unset_option ($name)&gt;

=item C&lt;unset_global_option ($name)&gt;

Unset an option.

=cut

sub unset_option ($)
{
  my ($name) = @_;
  delete $_options{$name};
}

sub unset_global_option ($)
{
  my ($name) = @_;
  delete $_global_options{$name};
}


=item C&lt;process_option_list (@list)&gt;

=item C&lt;process_global_option_list (@list)&gt;

Process Automake's option lists.  C&lt;@list&gt; should be a list of hash
references with keys C&lt;option&gt; and C&lt;where&gt;, where C&lt;option&gt; is an
option as they occur in C&lt;AUTOMAKE_OPTIONS&gt; or C&lt;AM_INIT_AUTOMAKE&gt;,
and C&lt;where&gt; is the location where that option occurred.

These functions should be called at most once for each set of options
having the same precedence; i.e., do not call it twice for two options
from C&lt;AM_INIT_AUTOMAKE&gt;.

Return 0 on error, 1 otherwise.

=cut

# $BOOL
# _option_is_from_configure ($OPTION, $WHERE)
# ----------------------------------------------
# Check that the $OPTION given in location $WHERE is specified with
# AM_INIT_AUTOMAKE, not with AUTOMAKE_OPTIONS.
sub _option_is_from_configure ($$)
{
  my ($opt, $where)= @_;
  return 1
    if $where-&gt;get =~ /^configure\./;
  error $where,
        "option '$opt' can only be used as argument to AM_INIT_AUTOMAKE\n" .
        "but not in AUTOMAKE_OPTIONS makefile statements";
  return 0;
}

# $BOOL
# _is_valid_easy_option ($OPTION)
# -------------------------------
# Explicitly recognize valid automake options that require no
# special handling by '_process_option_list' below.
sub _is_valid_easy_option ($)
{
  my $opt = shift;
  return scalar grep { $opt eq $_ } qw(
    check-news
    color-tests
    dejagnu
    dist-bzip2
    dist-lzip
    dist-xz
    dist-zip
    info-in-builddir
    no-define
    no-dependencies
    no-dist
    no-dist-gzip
    no-exeext
    no-installinfo
    no-installman
    no-texinfo.tex
    nostdinc
    readme-alpha
    serial-tests
    parallel-tests
    silent-rules
    std-options
    subdir-objects
  );
}

# $BOOL
# _process_option_list (\%OPTIONS, @LIST)
# ------------------------------------------
# Process a list of options.  \%OPTIONS is the hash to fill with options
# data.  @LIST is a list of options as get passed to public subroutines
# process_option_list() and process_global_option_list() (see POD
# documentation above).
sub _process_option_list (\%@)
{
  my ($options, @list) = @_;
  my @warnings = ();
  my $ret = 1;

  foreach my $h (@list)
    {
      local $_ = $h-&gt;{'option'};
      my $where = $h-&gt;{'where'};
      $options-&gt;{$_} = $where;
      if ($_ eq 'gnits' || $_ eq 'gnu' || $_ eq 'foreign')
        {
          set_strictness ($_);
        }
      # TODO: Remove this special check in Automake 3.0.
      elsif (/^(.*\/)?ansi2knr$/)
        {
          # Obsolete (and now removed) de-ANSI-fication support.
          error ($where,
                 "automatic de-ANSI-fication support has been removed");
          $ret = 0;
        }
      # TODO: Remove this special check in Automake 3.0.
      elsif ($_ eq 'cygnus')
        {
          error $where, "support for Cygnus-style trees has been removed";
          $ret = 0;
        }
      # TODO: Remove this special check in Automake 3.0.
      elsif ($_ eq 'dist-lzma')
        {
          error ($where, "support for lzma-compressed distribution " .
                         "archives has been removed");
          $ret = 0;
        }
      # TODO: Make this a fatal error in Automake 2.0.
      elsif ($_ eq 'dist-shar')
        {
          msg ('obsolete', $where,
               "support for shar distribution archives is deprecated.\n" .
               "  It will be removed in Automake 2.0");
        }
      # TODO: Make this a fatal error in Automake 2.0.
      elsif ($_ eq 'dist-tarZ')
        {
          msg ('obsolete', $where,
               "support for distribution archives compressed with " .
               "legacy program 'compress' is deprecated.\n" .
               "  It will be removed in Automake 2.0");
        }
      elsif (/^filename-length-max=(\d+)$/)
        {
          delete $options-&gt;{$_};
          $options-&gt;{'filename-length-max'} = [$_, $1];
        }
      elsif ($_ eq 'tar-v7' || $_ eq 'tar-ustar' || $_ eq 'tar-pax')
        {
          if (not _option_is_from_configure ($_, $where))
            {
              $ret = 0;
            }
          for my $opt ('tar-v7', 'tar-ustar', 'tar-pax')
            {
              next
                if $opt eq $_ or ! exists $options-&gt;{$opt};
              error ($where,
                     "options '$_' and '$opt' are mutually exclusive");
              $ret = 0;
            }
        }
      elsif (/^\d+\.\d+(?:\.\d+)?[a-z]?(?:-[A-Za-z0-9]+)?$/)
        {
          # Got a version number.
          if (Automake::Version::check ($VERSION, $&amp;))
            {
              error ($where, "require Automake $_, but have $VERSION");
              $ret = 0;
            }
        }
      elsif (/^(?:--warnings=|-W)(.*)$/)
        {
          my @w = map { { cat =&gt; $_, loc =&gt; $where} } split (',', $1);
          push @warnings, @w;
        }
      elsif (! _is_valid_easy_option $_)
        {
          error ($where, "option '$_' not recognized");
          $ret = 0;
        }
    }

  # We process warnings here, so that any explicitly-given warning setting
  # will take precedence over warning settings defined implicitly by the
  # strictness.
  foreach my $w (@warnings)
    {
      msg 'unsupported', $w-&gt;{'loc'},
          "unknown warning category '$w-&gt;{'cat'}'"
        if switch_warning $w-&gt;{cat};
    }

  return $ret;
}

sub process_option_list (@)
{
  prog_error "local options already processed"
    if $_options_processed;
  $_options_processed = 1;
  _process_option_list (%_options, @_);
}

sub process_global_option_list (@)
{
  prog_error "global options already processed"
    if $_global_options_processed;
  $_global_options_processed = 1;
  _process_option_list (%_global_options, @_);
}

=item C&lt;set_strictness ($name)&gt;

Set the current strictness level.
C&lt;$name&gt; should be one of C&lt;'foreign'&gt;, C&lt;'gnu'&gt;, or C&lt;'gnits'&gt;.

=cut

# Set strictness.
sub set_strictness ($)
{
  $strictness_name = $_[0];

  Automake::ChannelDefs::set_strictness ($strictness_name);

  if ($strictness_name eq 'gnu')
    {
      $strictness = GNU;
    }
  elsif ($strictness_name eq 'gnits')
    {
      $strictness = GNITS;
    }
  elsif ($strictness_name eq 'foreign')
    {
      $strictness = FOREIGN;
    }
  else
    {
      prog_error "level '$strictness_name' not recognized";
    }
}

1;
</pre></body></html>