autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

02: autoconf uses autom4te for expansion


From: Akim Demaille
Subject: 02: autoconf uses autom4te for expansion
Date: 24 Jul 2001 10:46:13 +0200
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Academic Rigor)

Index: ChangeLog
from  Akim Demaille  <address@hidden>

        Let autoconf use autom4te to create configure.

        * autoconf.in ($automate): New var.
        (task script): Use autom4te.
        * autom4te.in (File::Spec): Use it.
        (&find_file): New.
        (&parse_args): --warning is -W, not -w.
        Find the top level files.
        (&handle_m4): Pass the warnings flags.
        Don't report verbosely m4's failures, unless requested.
        (&handle_output): Don't complain for forbidden tokens in comments.
        Be sure to report all the forbidden tokens within a single line.
        (&trace_format_to_m4): Preserve `$_'.
        (&handle_traces): Sort the output macros.
        (&up_to_date_p): Find the files before trying to get its time stamp.

Index: Makefile.am
--- Makefile.am Sun, 15 Jul 2001 16:36:26 +0200 akim (ace/45_Makefile.a 1.50 
644)
+++ Makefile.am Mon, 23 Jul 2001 20:05:15 +0200 akim (ace/45_Makefile.a 1.50 
644)
@@ -124,6 +124,7 @@
        -e 's,@prefix\@,$(prefix),g' \
        -e 's,@autoconf-name\@,'`echo autoconf | sed '$(transform)'`',g' \
        -e 's,@autoheader-name\@,'`echo autoheader | sed '$(transform)'`',g' \
+       -e 's,@autom4te-name\@,'`echo autom4te | sed '$(transform)'`',g' \
        -e 's,@M4\@,$(M4),g' \
        -e 's,@AWK\@,$(AWK),g' \
        -e 's,@VERSION\@,$(VERSION),g' \
Index: autoconf.in
--- autoconf.in Sun, 15 Jul 2001 12:34:11 +0200 akim (ace/17_autoconf.s 
1.31.8.46 644)
+++ autoconf.in Mon, 23 Jul 2001 20:05:15 +0200 akim (ace/17_autoconf.s 
1.31.8.46 644)
@@ -125,6 +125,16 @@
 fi


+# We test "$dir/autom4te" in case we are in the build tree, in which case
+# the names are not transformed yet.
+for autom4te in "$AUTOM4TE" \
+                "$dir/@autom4te-name@" \
+                "$dir/autom4te" \
+                "@bindir@/@autom4te-name@"; do
+  test -f "$autom4te" && break
+done
+
+
 # Variables.
 : address@hidden@}}
 test -z "$AC_ACLOCALDIR" &&
@@ -235,23 +245,6 @@
   esac
 done

-# The warnings are the concatenation of 1. application's defaults,
-# 2. $WARNINGS, $3 command line options, in that order.
-# Set them in the order expected by the M4 macros: the converse.
-alphabet='abcdefghijklmnopqrstuvwxyz'
-ALPHABET='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-NUMBERS='0123456789'
-WORDCHAR=_$alphabet$ALPHABET$NUMBERS
-
-m4_warnings=
-for warning in `IFS=,; echo syntax $WARNINGS $warnings |
-                         tr $ALPHABET $alphabet`
-do
-  test -n $warning || continue
-  m4_warnings="$warning"`test -n "$m4_warnings" && echo ",$m4_warnings"`
-done
-
-
 # Trap on 0 to stop playing with `rm'.
 $debug ||
 {
@@ -282,6 +275,16 @@
 m4f_prefiles="--reload-state=$autoconf_dir/autoconf.m4f $acsite_m4 $aclocal_m4"
 run_m4="$M4 $m4_common"

+# Running autom4te.
+run_autom4te="$autom4te "\
+`$verbose "--verbose "`\
+`$debug && echo "--debug "`\
+"--include $autoconf_dir --include $localdir "\
+"--warning syntax,$warnings "\
+"autoconf.m4"`$initialization || echo f`" "\
+"$acsite_m4 "\
+"$aclocal_m4 "
+
 # Find the input file.
 case $# in
   0)
@@ -316,14 +319,6 @@
   (exit 1); exit 1
 fi

-# Output is produced into FD 4.  Prepare it.
-case $outfile in
- -)  # Output to stdout
-  exec 4>&1 ;;
- * )
-  exec 4>$outfile;;
-esac
-
 # Initializations are performed.  Proceed to the main task.
 case $task in

@@ -334,123 +329,14 @@
   # M4 expansion.
   : >$tmp/forbidden.rx
   : >$tmp/allowed.rx
-  $verbose "$me: running $run_m4 -Dm4_warnings=$m4_warnings $m4f_prefiles 
$infile" >&2
-  $run_m4 -Dm4_warnings=$m4_warnings $m4f_prefiles $infile >$tmp/configure ||
+  $verbose "$me: running $run_autom4te $infile --output $outfile" >&2
+  $run_autom4te $infile --output $outfile ||
     { (exit 1); exit 1; }

   if test "x$outfile" != x-; then
     chmod +x $outfile
   fi

-  # Put the real line numbers into configure to make config.log more
-  # helpful.  Because quoting can sometimes get really painful in m4,
-  # there are special @tokens@ to substitute.
-  sed 's/^    //' >"$tmp/finalize.awk" <<EOF
-    # Load the list of tokens which escape the forbidden patterns.
-    BEGIN {
-      # Be sure the read GAWK documentation to understand the parens
-      # around \`tmp "/forbidden.rx"'.
-      while ((getline pattern < (tmp "/forbidden.rx")) > 0)
-        forbidden = (forbidden ? forbidden "|" : "") pattern
-      close (tmp "/forbidden.rx")
-      if (verbose)
-        errprint("$me: forbidden: " forbidden)
-
-      while ((getline pattern < (tmp "/allowed.rx")) > 0)
-        allowed = (allowed ? allowed "|" : "") pattern
-      if (!allowed)
-        allowed = "^$"
-      close (tmp "/allowed.rx")
-      if (verbose)
-        errprint("$me: allowed: " allowed)
-    }
-
-    function errprint (message)
-    {
-      # BAD! the pipe to 'cat >&2' doesn't work for DJGPP.
-      #  print message | "cat >&2"
-      # Use normal redirection instead:
-      print message > "$tmp/finalize.err"
-    }
-
-    function undefined (file, line, macro)
-    {
-      errprint(file ":" line ": error: possibly undefined macro: " macro)
-    }
-
-    # Body.
-    {
-      sub (/[ \t]*$/, "")
-      if (\$0 == "")
-        {
-          if (!duplicate)
-            {
-               oline++
-               print
-            }
-          duplicate = 1
-          next
-        }
-      duplicate = 0
-      oline++
-      if (\$0 ~ /__oline__/)
-        while (sub (/__oline__/, oline))
-          continue
-      while (sub (/@<:@/, "["))
-        continue
-      while (sub (/@:>@/, "]"))
-        continue
-      while (sub (/@S\|@/, "$"))
-        continue
-      while (sub (/@%:@/, "#"))
-        continue
-
-      print
-
-      # Dubious feature: we tolerate macro names when commented.
-      sub (/#.*/, "")
-
-      # Get the tokens.
-      split (\$0, tokens, /[^$WORDCHAR]*/)
-
-      for (token in tokens)
-        if (match (tokens[token], forbidden) &&
-            !match (tokens[token], allowed))
-          {
-            macros [tokens [token]] = oline
-            some_macros_were_not_expanded = 1
-          }
-    }
-
-    # If there are some macros which are left unexpanded in the output,
-    # try to find the input which is responsible.  Otherwise, try to help.
-    END {
-      if (some_macros_were_not_expanded)
-        {
-          line = 0
-          while (getline < "$infile")
-            {
-              line++
-              for (macro in macros)
-                if (index (\$0, macro))
-                  {
-                    delete macros [macro]
-                    undefined("$infile", line, macro)
-                  }
-            }
-          close ("$infile")
-          for (macro in macros)
-            undefined("$outfile", macros [macro], macro)
-          exit 1
-        }
-    }
-EOF
-    $AWK -v tmp="$tmp" \
-         `$verbose "-v verbose=1"` \
-         -f "$tmp/finalize.awk" <$tmp/configure >&4 ||
-      { test -f "$tmp/finalize.err" && cat "$tmp/finalize.err" >&2
-        (exit 1); exit 1; }
-    test -f "$tmp/finalize.err" && cat "$tmp/finalize.err" >&2
   ;; # End of the task script.


@@ -755,6 +641,14 @@
       echo "$me: tracing failed" >&2
       (exit 1); exit 1
     }
+
+  # Output is produced into FD 4.  Prepare it.
+  case $outfile in
+   -)  # Output to stdout
+    exec 4>&1 ;;
+   * )
+    exec 4>$outfile;;
+  esac

   $verbose "$me: running $M4 $tmp/trace.m4" >&2
   sed -f $tmp/trace2m4.sed $tmp/traces |
Index: autoconf.m4
--- autoconf.m4 Mon, 04 Jun 2001 18:29:01 +0200 akim (ace/28_autoconf.m 1.20 
644)
+++ autoconf.m4 Mon, 23 Jul 2001 20:05:15 +0200 akim (ace/28_autoconf.m 1.20 
644)
@@ -1,4 +1,4 @@
-include(m4sh.m4)#                                        -*- Autoconf -*-
+changequote()changequote([, ])include(m4sh.m4)#            -*- Autoconf -*-
 # This file is part of Autoconf.
 # Driver that loads the Autoconf macro files.
 # Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
Index: autom4te.in
--- autom4te.in Sun, 15 Jul 2001 16:36:26 +0200 akim (ace/c/10_autom4te.i 1.2 
664)
+++ autom4te.in Mon, 23 Jul 2001 20:11:31 +0200 akim (ace/c/10_autom4te.i 1.2 
664)
@@ -47,6 +47,7 @@
 use Carp;
 use Getopt::Long;
 use IO::File;
+use File::Spec;
 use strict;

 # List of requests
@@ -242,8 +243,12 @@ sub load
 my $output = '-';
 my @warning;

+# M4 include path.
 my @include;

+# 0 for EXIT_SUCCESS.
+my $exit_status = 0;
+
 # $M4.
 my $m4 = $ENV{"M4"} || '@M4@';
 # Some non-GNU m4's don't reject the --help option, so give them /dev/null.
@@ -334,9 +339,38 @@ sub xsystem ($)
   (system $command) == 0
     or die ("$me: "
            . (split (' ', $command))[0]
-           . " failed with exit status: $?\n");
+           . " failed with exit status: "
+           . ($? >> 8)
+           . "\n");
 }

+
+# $FILENAME
+# find_file ($FILENAME)
+# ---------------------
+# We match exactly the behavior of GNU m4: first look in the current
+# directory (which includes the case of absolute file names), and, if
+# the file is not absolute, just fail.  Otherwise, look in the path.
+sub find_file ($)
+{
+  my ($filename) = @_;
+
+  return File::Spec->canonpath ($filename)
+    if -f $filename;
+
+  die "$me: no such for or directory: $filename\n"
+    if File::Spec->file_name_is_absolute ($filename);
+
+  foreach my $path (@include)
+    {
+      return File::Spec->canonpath (File::Spec->catfile ($path, $filename))
+       if -f File::Spec->catfile ($path, $filename)
+    }
+
+  die "$me: programming error";
+}
+
+
 # print_usage ()
 # --------------
 # Display usage (--help).
@@ -416,7 +450,7 @@ sub parse_args ()
      "v|verbose"    => \$verbose,
      "d|debug"      => \$debug,
      "o|output=s"   => \$output,
-     "w|warnings=s" => address@hidden,
+     "W|warnings=s" => address@hidden,

      # Library directories:
      "I|include=s" => address@hidden,
@@ -441,16 +475,24 @@ sub parse_args ()
   die "$me: too few arguments
 Try `$me --help' for more information.\n"
     unless @ARGV;
+
+  # We don't want to depend upon m4's --include to find the top level
+  # files.  Try to get a canonical name, as it's a key for caching.
+  for (my $i = 0; $i < $#ARGV; ++$i)
+    {
+      $ARGV[$i] = find_file ($ARGV[$i]);
+    }
 }


 # handle_m4 ($REQ, @TRACE)
 # ------------------------
 # Run m4 on the input files, and save the traces on the @TRACE macros.
-sub handle_m4 ($%)
+sub handle_m4 ($@)
 {
   my ($req, @trace) = @_;

+  # Find the files.  We don't want to depend upon m4's --include.
   # *.m4f files have to be reloaded.
   my $files;
   foreach (@ARGV)
@@ -461,19 +503,33 @@ sub handle_m4 ($%)
       $files .= "$_";
     }

+  # The warnings are the concatenation of 1. application's defaults,
+  # 2. $WARNINGS, $3 command line options, in that order.
+  # Set them in the order expected by the M4 macros: the converse.
+  my $m4_warnings =
+    lc join (',', reverse (split (',', ($ENV{'WARNINGS'} || '')),
+                          map { split /,/ } @warning));
+
   # GNU m4 appends when using --error-output.
   unlink ("$me.cache/" . $req->cache);

   # Run m4.
-  xsystem ("$m4"
-          . " --define m4_tmpdir=$tmp"
-          . " --define m4_warnings=" # FIXME: Pass the warnings.
-          . ' --debug=aflq'
-          . " --error-output=$me.cache/" . $req->cache
-          . join (' --trace=',   '', @trace)
-          . join (' --include=', '', @include)
-          . $files
-          . " >$tmp/output");
+  my $command = ("$m4"
+                . " --define m4_tmpdir=$tmp"
+                . " --define m4_warnings=$m4_warnings"
+                . ' --debug=aflq'
+                . " --error-output=$me.cache/" . $req->cache
+                . join (' --trace=',   '', @trace)
+                . join (' --include=', '', @include)
+                . $files
+                . " >$tmp/output");
+  verbose "running: $command";
+  system $command;
+  if ($?)
+    {
+      verbose "$m4: failed with exit status: " . ($? >> 8) . "\n";
+      exit $? >> 8;
+    }
 }


@@ -534,33 +590,48 @@ sub handle_output ($)

       print $out "$_\n";

-      foreach (split ('\W+'))
+      # Don't complain in comments.  Well, until we have something
+      # better, don't consider `#include' etc. are comments.
+      s/\#.*//
+       unless /^\#(if|include|endif|ifdef|ifndef|define)\b/;
+      foreach (split (/\W+/))
        {
          $prohibited{$_} = $oline
            if /$forbidden/ && !/$allowed/;
        }
     }

-  if (%prohibited)
-    {
-      my $prohibited = '\b(' . join ('|', keys %prohibited) . ')\b';
-      my $in = new IO::File ($ARGV[$#ARGV])
-        or die "$me: cannot open $ARGV[$#ARGV]: $!\n";
+  # If no forbidden words, we're done.
+  return
+    if ! %prohibited;
+
+  # Locate the forbidden words in the last source file.
+  # This is unsatisfying but...
+  my $prohibited = '\b(' . join ('|', keys %prohibited) . ')\b';
+  my $file = new IO::File ($ARGV[$#ARGV])
+    or die "$me: cannot open $ARGV[$#ARGV]: $!\n";
+  $exit_status = 1;
+
+  while ($_ = $file->getline)
+    {
+      # Don't complain in comments.  Well, until we have something
+      # better, don't consider `#include' etc. are comments.
+      s/\#.*//
+       unless /^\#(if|include|endif|ifdef|ifndef|define)\b/;

-      while ($_ = $in->getline)
-        {
-         if (/$prohibited/)
-           {
-             warn "$ARGV[$#ARGV]: $.: undefined macro: $1\n"
-               if exists $prohibited{$1};
-             delete $prohibited{$1};
-           }
-       }
-      foreach (keys %prohibited)
+      # Complain once per word, but possibly several times per line.
+      while (/$prohibited/)
        {
-         warn "$output: $prohibited{$_}: undefined macro: $_\n";
+         warn "$ARGV[$#ARGV]:$.: error: possibly undefined macro: $1\n";
+         delete $prohibited{$1};
+         # If we're done, exit.
+         return
+           if ! %prohibited;
+         $prohibited = '\b(' . join ('|', keys %prohibited) . ')\b';
        }
     }
+  warn "$output:$prohibited{$_}: error: possibly undefined macro: $_\n"
+    foreach (keys %prohibited);
 }


@@ -600,6 +671,7 @@ sub trace_requests
 sub trace_format_to_m4 ($)
 {
   my ($format) = @_;
+  my ($underscore) = $_;
   my %escape = (# File name.
                'f' => '$1',
                # Line number.
@@ -656,6 +728,7 @@ sub trace_format_to_m4 ($)
         }
     }

+  $_ = $underscore;
   return '[[' . $res . ']]';
 }

@@ -714,7 +787,7 @@ sub handle_traces ($$%)
        }
     }

-  verbose "formatting traces for `$output': ", join (', ', keys %trace);
+  verbose "formatting traces for `$output': ", join (', ', sort keys %trace);

   # Processing the traces.
   my $trace_m4 = new IO::File (">$tmp/traces.m4")
@@ -788,7 +861,7 @@ sub handle_traces ($$%)
    "## -------------------------------------- ##\n",
    "\n";
   print $trace_m4 "at_define([AT_$_], [at_dnl])\n"
-    foreach (keys %{$req->macro});
+    foreach (sort keys %{$req->macro});
   print $trace_m4 "\n";

   # Implement traces for current requests (%TRACE).
@@ -797,10 +870,13 @@ sub handle_traces ($$%)
     "## Trace processing macros.  ##\n",
     "## ------------------------- ##\n",
     "\n";
-  foreach my $key (keys %trace)
+  foreach (sort keys %trace)
     {
-      print $trace_m4 "at_define([AT_$key],\n";
-      print $trace_m4 trace_format_to_m4 ($trace{$key}) . ")\n\n";
+      # Trace request can be embed \n.
+      (my $comment = "Trace $_:$trace{$_}") =~ s/^/\# /;
+      print $trace_m4 "$comment\n";
+      print $trace_m4 "at_define([AT_$_],\n";
+      print $trace_m4 trace_format_to_m4 ($trace{$_}) . ")\n\n";
     }
   print $trace_m4 "\n";

@@ -828,7 +904,6 @@ sub handle_traces ($$%)
       # Single line traces, as the example above.
       s{^m4trace:(.+):(\d+): -(\d+)- (.*)$}
        {AT_$4([$1], [$2], [$3], [$4]};
-
       print $trace_m4 "$_";
     }
   $trace_m4->close;
@@ -873,18 +948,15 @@ sub up_to_date_p ($$)

   # Files may include others.  We can use traces since we just checked
   # if they are available.
-  handle_traces ($req, "$tmp/dependencies", ('include' => '$1'));
+  # If $FILE is younger than one of its dependencies, it is outdated.
+  handle_traces ($req, "$tmp/dependencies",('include' => '$1'));
+  my $mtime = (stat ($file))[9];
   my $deps = new IO::File ("$tmp/dependencies");
   while ($_ = $deps->getline)
     {
       chop;
-      push @dep, $_;
-    }
-
-  # If $FILE is younger than one of its dependencies, it is outdated.
-  my $mtime = (stat ($file))[9];
-  foreach (@dep)
-    {
+      $_ = find_file ($_);
+      verbose "$file depends on $_";
       if ($mtime < (stat ($_))[9])
        {
          verbose "$file depends on $_ which is more recent";
@@ -952,4 +1024,4 @@ sub up_to_date_p ($$)

 Request->save ("$me.cache/requests");

-exit 0;
+exit $exit_status;
Index: m4sh.m4
--- m4sh.m4 Sat, 23 Jun 2001 23:01:08 +0200 akim (ace/b/41_m4sh.m4 1.28 644)
+++ m4sh.m4 Mon, 23 Jul 2001 20:05:15 +0200 akim (ace/b/41_m4sh.m4 1.28 644)
@@ -1,4 +1,4 @@
-include(m4sugar.m4)#                                        -*- Autoconf -*-
+changequote()changequote([, ])include(m4sugar.m4)#         -*- Autoconf -*-
 # This file is part of Autoconf.
 # M4 sugar for common shell constructs.
 # Requires GNU M4 and M4sugar.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]